Compare commits
1
Commits
main
..
01d0289091
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01d0289091 |
No files matched your search
@@ -1,50 +0,0 @@
|
|||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
charset = utf-8
|
|
||||||
|
|
||||||
[*.{json,toml,yml,gyp,xml}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
|
|
||||||
[*.{js,ts}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
|
|
||||||
[*.scm]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
|
|
||||||
[*.{c,cc,h}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
||||||
|
|
||||||
[*.rs]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
||||||
|
|
||||||
[*.{py,pyi}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
||||||
|
|
||||||
[*.swift]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
||||||
|
|
||||||
[*.java]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
||||||
|
|
||||||
[*.go]
|
|
||||||
indent_style = tab
|
|
||||||
indent_size = 8
|
|
||||||
|
|
||||||
[Makefile]
|
|
||||||
indent_style = tab
|
|
||||||
indent_size = 8
|
|
||||||
|
|
||||||
[parser.c]
|
|
||||||
indent_size = 2
|
|
||||||
|
|
||||||
[{alloc,array,parser}.h]
|
|
||||||
indent_size = 2
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
* text=auto eol=lf
|
|
||||||
|
|
||||||
# Generated source files
|
|
||||||
src/*.json linguist-generated
|
|
||||||
src/parser.c linguist-generated
|
|
||||||
src/tree_sitter/* linguist-generated
|
|
||||||
|
|
||||||
# C bindings
|
|
||||||
bindings/c/** linguist-generated
|
|
||||||
CMakeLists.txt linguist-generated
|
|
||||||
Makefile linguist-generated
|
|
||||||
|
|
||||||
# Rust bindings
|
|
||||||
bindings/rust/* linguist-generated
|
|
||||||
Cargo.toml linguist-generated
|
|
||||||
Cargo.lock linguist-generated
|
|
||||||
|
|
||||||
# Node.js bindings
|
|
||||||
bindings/node/* linguist-generated
|
|
||||||
binding.gyp linguist-generated
|
|
||||||
package.json linguist-generated
|
|
||||||
package-lock.json linguist-generated
|
|
||||||
|
|
||||||
# Python bindings
|
|
||||||
bindings/python/** linguist-generated
|
|
||||||
setup.py linguist-generated
|
|
||||||
pyproject.toml linguist-generated
|
|
||||||
|
|
||||||
# Go bindings
|
|
||||||
bindings/go/* linguist-generated
|
|
||||||
go.mod linguist-generated
|
|
||||||
go.sum linguist-generated
|
|
||||||
|
|
||||||
# Swift bindings
|
|
||||||
bindings/swift/** linguist-generated
|
|
||||||
Package.swift linguist-generated
|
|
||||||
Package.resolved linguist-generated
|
|
||||||
|
|
||||||
# Zig bindings
|
|
||||||
bindings/zig/* linguist-generated
|
|
||||||
build.zig linguist-generated
|
|
||||||
build.zig.zon linguist-generated
|
|
||||||
|
|
||||||
# Java bindings
|
|
||||||
pom.xml linguist-generated
|
|
||||||
bindings/java/** linguist-generated
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
name: CI
|
|
||||||
|
|
||||||
# Pull requests run this directly; pushes to main reach it through release.yml,
|
|
||||||
# which calls this workflow before it tags and publishes.
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
workflow_call:
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ci-${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
parser:
|
|
||||||
name: Corpus and generated files
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
- uses: actions/setup-node@v5
|
|
||||||
with:
|
|
||||||
node-version: 22
|
|
||||||
cache: npm
|
|
||||||
- run: npm ci
|
|
||||||
- name: Corpus tests
|
|
||||||
run: npm run parser-test
|
|
||||||
- name: src/ matches grammar.js
|
|
||||||
run: |
|
|
||||||
npm run parser-generate
|
|
||||||
if ! git diff --exit-code --stat src/; then
|
|
||||||
echo "::error::src/ is out of date: run 'npm run parser-generate' and commit the result"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
node:
|
|
||||||
name: Node binding (${{ matrix.os }})
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
- uses: actions/setup-node@v5
|
|
||||||
with:
|
|
||||||
node-version: 22
|
|
||||||
cache: npm
|
|
||||||
# windows-latest is Windows Server 2025 with Visual Studio 2026, which the
|
|
||||||
# node-gyp bundled with the runner's npm (11.5) reports as "unknown
|
|
||||||
# version undefined" and then gives up on. node-gyp learned VS 18 in
|
|
||||||
# 12.1.0 and npm 12 bundles 13.
|
|
||||||
- if: runner.os == 'Windows'
|
|
||||||
run: npm install -g npm@^12
|
|
||||||
# npm ci builds the addon through the install script (node-gyp-build)
|
|
||||||
- run: npm ci
|
|
||||||
- run: npm run binding-test
|
|
||||||
|
|
||||||
rust:
|
|
||||||
name: Rust binding
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
- run: cargo test
|
|
||||||
|
|
||||||
python:
|
|
||||||
name: Python binding
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
- uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: "3.12"
|
|
||||||
- run: python -m pip install --upgrade pip
|
|
||||||
- run: python -m pip install . "tree-sitter~=0.24"
|
|
||||||
- run: python -m unittest discover -s bindings/python/tests -v
|
|
||||||
|
|
||||||
go:
|
|
||||||
name: Go binding
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: stable
|
|
||||||
- run: go test ./bindings/go/
|
|
||||||
|
|
||||||
swift:
|
|
||||||
name: Swift binding
|
|
||||||
runs-on: macos-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
- run: swift build
|
|
||||||
@@ -1,245 +0,0 @@
|
|||||||
name: Release
|
|
||||||
|
|
||||||
# Releasing is a version bump: push a commit to main that changes the version in
|
|
||||||
# package.json, and this tags v<version>, creates the GitHub release and stages
|
|
||||||
# the npm publish. Every other push to main only runs the tests.
|
|
||||||
#
|
|
||||||
# Staging is not publishing: "npm stage publish" hands npm the tarball and nobody
|
|
||||||
# can install it until a maintainer runs "npm stage approve <stage-id>" and
|
|
||||||
# answers a 2FA prompt. That is the point — npm is deprecating the tokens that
|
|
||||||
# let a workflow publish on its own, and staging defers the proof of presence
|
|
||||||
# instead of removing it. The job summary carries the command to run.
|
|
||||||
#
|
|
||||||
# Running it by hand instead stages whatever version package.json holds, as long
|
|
||||||
# as npm has neither published nor staged it yet, and skips the tag and the
|
|
||||||
# release if a previous attempt already made them. That is how a half-finished
|
|
||||||
# release is retried.
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: release-${{ github.ref }}
|
|
||||||
cancel-in-progress: false
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
version:
|
|
||||||
name: Version
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
version: ${{ steps.check.outputs.version }}
|
|
||||||
changed: ${{ steps.check.outputs.changed }}
|
|
||||||
tag_exists: ${{ steps.check.outputs.tag_exists }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
with:
|
|
||||||
fetch-depth: 2
|
|
||||||
fetch-tags: true
|
|
||||||
- id: check
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
GITHUB_EVENT_NAME: ${{ github.event_name }}
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
name="$(node -p "require('./package.json').name")"
|
|
||||||
version="$(node -p "require('./package.json').version")"
|
|
||||||
echo "version=$version" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
if git rev-parse -q --verify "refs/tags/v$version" >/dev/null; then
|
|
||||||
tag_exists=true
|
|
||||||
else
|
|
||||||
tag_exists=false
|
|
||||||
fi
|
|
||||||
echo "tag_exists=$tag_exists" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
if [ "$GITHUB_EVENT_NAME" = "workflow_dispatch" ]; then
|
|
||||||
# by hand: stage what package.json says, unless npm has it already.
|
|
||||||
# A version staged but not yet approved is invisible to npm view; the
|
|
||||||
# stage job looks for that one itself.
|
|
||||||
if npm view "$name@$version" version >/dev/null 2>&1; then
|
|
||||||
echo "::warning::$name@$version is already on npm; nothing to stage"
|
|
||||||
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
||||||
else
|
|
||||||
echo "staging $name@$version by hand (tag exists: $tag_exists)"
|
|
||||||
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
||||||
fi
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if git cat-file -e HEAD~1:package.json 2>/dev/null; then
|
|
||||||
previous="$(git show HEAD~1:package.json | node -p "JSON.parse(require('node:fs').readFileSync(0, 'utf8')).version")"
|
|
||||||
else
|
|
||||||
previous=""
|
|
||||||
fi
|
|
||||||
if [ "$version" = "$previous" ]; then
|
|
||||||
echo "version is unchanged at $version; not releasing"
|
|
||||||
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
||||||
elif [ "$tag_exists" = "true" ]; then
|
|
||||||
echo "::warning::tag v$version already exists; not releasing"
|
|
||||||
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
||||||
else
|
|
||||||
echo "releasing $previous -> $version"
|
|
||||||
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
||||||
fi
|
|
||||||
|
|
||||||
ci:
|
|
||||||
name: CI
|
|
||||||
needs: version
|
|
||||||
uses: ./.github/workflows/ci.yml
|
|
||||||
|
|
||||||
prebuild:
|
|
||||||
name: Prebuild (${{ matrix.os }})
|
|
||||||
needs: [version, ci]
|
|
||||||
if: needs.version.outputs.changed == 'true'
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: true
|
|
||||||
matrix:
|
|
||||||
# one runner per platform and architecture npm should ship a binary for;
|
|
||||||
# the arm Linux runner is free for public repositories only
|
|
||||||
os:
|
|
||||||
[
|
|
||||||
ubuntu-latest,
|
|
||||||
ubuntu-24.04-arm,
|
|
||||||
macos-latest,
|
|
||||||
windows-latest,
|
|
||||||
]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
- uses: actions/setup-node@v5
|
|
||||||
with:
|
|
||||||
node-version: 22
|
|
||||||
cache: npm
|
|
||||||
# the Windows runner's own npm bundles a node-gyp too old to see the
|
|
||||||
# Visual Studio 2026 on that image; see ci.yml
|
|
||||||
- if: runner.os == 'Windows'
|
|
||||||
run: npm install -g npm@^12
|
|
||||||
- run: npm ci
|
|
||||||
- run: npm run prebuildify
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: prebuilds-${{ matrix.os }}
|
|
||||||
path: prebuilds/
|
|
||||||
if-no-files-found: error
|
|
||||||
|
|
||||||
publish:
|
|
||||||
name: Tag and stage
|
|
||||||
needs: [version, prebuild]
|
|
||||||
if: needs.version.outputs.changed == 'true'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: write # the tag and the release
|
|
||||||
id-token: write # the OIDC exchange, and provenance for npm
|
|
||||||
env:
|
|
||||||
VERSION: ${{ needs.version.outputs.version }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
- uses: actions/setup-node@v5
|
|
||||||
with:
|
|
||||||
node-version: 22
|
|
||||||
cache: npm
|
|
||||||
registry-url: https://registry.npmjs.org
|
|
||||||
- name: Collect the prebuilds
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
pattern: prebuilds-*
|
|
||||||
path: prebuilds/
|
|
||||||
merge-multiple: true
|
|
||||||
- run: ls -R prebuilds/
|
|
||||||
- run: npm ci
|
|
||||||
# tree-sitter build --wasm needs Emscripten; the CLI runs it through
|
|
||||||
# Docker, which the ubuntu runners have
|
|
||||||
- name: Build the Wasm parser
|
|
||||||
run: npm run parser-build
|
|
||||||
# a retry of a half-finished release finds its tag and release already made
|
|
||||||
- name: Tag
|
|
||||||
if: needs.version.outputs.tag_exists != 'true'
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
git config user.name "github-actions[bot]"
|
|
||||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
||||||
git tag -a "v$VERSION" -m "v$VERSION"
|
|
||||||
git push origin "v$VERSION"
|
|
||||||
- name: Release
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ github.token }}
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
if gh release view "v$VERSION" >/dev/null 2>&1; then
|
|
||||||
echo "release v$VERSION exists; replacing its Wasm build"
|
|
||||||
gh release upload "v$VERSION" tree-sitter-django.wasm --clobber
|
|
||||||
else
|
|
||||||
gh release create "v$VERSION" --title "v$VERSION" --generate-notes tree-sitter-django.wasm
|
|
||||||
fi
|
|
||||||
# "npm stage" arrived in npm 12, which is newer than the npm any runner
|
|
||||||
# image ships with
|
|
||||||
- name: Install npm 12
|
|
||||||
run: npm install -g npm@^12
|
|
||||||
# staged versions share npm's version index with published ones, so a
|
|
||||||
# second stage of the same version is an error rather than a no-op. A run
|
|
||||||
# that staged and then failed later should find its stage and go on.
|
|
||||||
- name: Look for an existing stage
|
|
||||||
id: staged
|
|
||||||
env:
|
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
||||||
run: |
|
|
||||||
set -uo pipefail
|
|
||||||
name="$(node -p "require('./package.json').name")"
|
|
||||||
# a short-lived OIDC token cannot run "npm stage list" at all, so a
|
|
||||||
# failure here means "ask npm by staging", not "stop"
|
|
||||||
if ! items="$(npm stage list "$name" --json 2>/dev/null)"; then
|
|
||||||
echo "could not list staged versions; assuming there are none"
|
|
||||||
echo "staged=false" >> "$GITHUB_OUTPUT"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
id="$(node -e '
|
|
||||||
const items = JSON.parse(require("node:fs").readFileSync(0, "utf8"));
|
|
||||||
const match = items.find((item) => item.version === process.env.VERSION);
|
|
||||||
if (match) console.log(match.id);
|
|
||||||
' <<< "$items")"
|
|
||||||
if [ -n "$id" ]; then
|
|
||||||
echo "::warning::$name@$VERSION is already staged as $id; not staging it again"
|
|
||||||
echo "staged=true" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "stage_id=$id" >> "$GITHUB_OUTPUT"
|
|
||||||
else
|
|
||||||
echo "staged=false" >> "$GITHUB_OUTPUT"
|
|
||||||
fi
|
|
||||||
# NPM_TOKEN is the fallback: where the package has a trusted publisher for
|
|
||||||
# this workflow, npm exchanges the OIDC token above for one of its own and
|
|
||||||
# the secret is not read at all.
|
|
||||||
- name: Stage the publish
|
|
||||||
id: stage
|
|
||||||
if: steps.staged.outputs.staged != 'true'
|
|
||||||
env:
|
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
npm stage publish --provenance --access public 2>&1 | tee stage.log
|
|
||||||
id="$(sed -n 's/.*staged with id \([0-9a-fA-F-]\{36\}\).*/\1/p' stage.log | tail -n1)"
|
|
||||||
echo "stage_id=$id" >> "$GITHUB_OUTPUT"
|
|
||||||
- name: Say how to approve it
|
|
||||||
env:
|
|
||||||
STAGE_ID: ${{ steps.stage.outputs.stage_id || steps.staged.outputs.stage_id }}
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
name="$(node -p "require('./package.json').name")"
|
|
||||||
{
|
|
||||||
echo "### $name@$VERSION is staged, not published"
|
|
||||||
echo
|
|
||||||
echo "npm has the tarball and nobody can install it until a maintainer approves it, which asks for 2FA:"
|
|
||||||
echo
|
|
||||||
echo '```sh'
|
|
||||||
if [ -n "$STAGE_ID" ]; then
|
|
||||||
echo "npm stage view $STAGE_ID # what was staged"
|
|
||||||
echo "npm stage download $STAGE_ID # the tarball itself"
|
|
||||||
echo "npm stage approve $STAGE_ID # publish it"
|
|
||||||
echo "npm stage reject $STAGE_ID # throw it away"
|
|
||||||
else
|
|
||||||
echo "npm stage list $name"
|
|
||||||
echo "npm stage approve <stage-id>"
|
|
||||||
fi
|
|
||||||
echo '```'
|
|
||||||
echo
|
|
||||||
echo "Approving needs npm 12: \`npm install -g npm@^12\`."
|
|
||||||
} >> "$GITHUB_STEP_SUMMARY"
|
|
||||||
+1
-29
@@ -1,30 +1,2 @@
|
|||||||
node_modules
|
node_modules
|
||||||
tree-sitter-django.wasm
|
tree-sitter-django.wasm
|
||||||
|
|
||||||
# Node binding
|
|
||||||
build/
|
|
||||||
prebuilds/
|
|
||||||
*.node
|
|
||||||
|
|
||||||
# Rust binding
|
|
||||||
target/
|
|
||||||
Cargo.lock
|
|
||||||
|
|
||||||
# Python binding
|
|
||||||
dist/
|
|
||||||
*.egg-info/
|
|
||||||
__pycache__/
|
|
||||||
*.so
|
|
||||||
*.pyd
|
|
||||||
|
|
||||||
# C binding
|
|
||||||
*.o
|
|
||||||
*.a
|
|
||||||
*.dylib
|
|
||||||
libtree-sitter-django.*
|
|
||||||
|
|
||||||
# Swift binding
|
|
||||||
.build/
|
|
||||||
Package.resolved
|
|
||||||
*.pc
|
|
||||||
*.tgz
|
|
||||||
@@ -11,10 +11,6 @@ npm run parser-generate # regenerate src/parser.c, grammar.json, node-types.js
|
|||||||
npm run parser-test # run the corpus tests
|
npm run parser-test # run the corpus tests
|
||||||
npm run parser-build # build tree-sitter-django.wasm
|
npm run parser-build # build tree-sitter-django.wasm
|
||||||
npm run playground # explore the grammar interactively
|
npm run playground # explore the grammar interactively
|
||||||
npm install # also builds the Node binding, through node-gyp-build
|
|
||||||
npm run binding-test # the Node binding's own test
|
|
||||||
cargo test # the Rust binding
|
|
||||||
make # the C library, and make clean to remove it
|
|
||||||
|
|
||||||
npx tree-sitter test -i "Cycle With As" # one test, by name regex
|
npx tree-sitter test -i "Cycle With As" # one test, by name regex
|
||||||
npx tree-sitter test --file-name cycle.txt # one corpus file
|
npx tree-sitter test --file-name cycle.txt # one corpus file
|
||||||
@@ -34,95 +30,6 @@ back, producing churn in both directions.
|
|||||||
`npm run lint` does not work: `eslint.config.mjs` was copied from a Next.js project and enables
|
`npm run lint` does not work: `eslint.config.mjs` was copied from a Next.js project and enables
|
||||||
`@typescript-eslint` and `react-hooks` rules whose plugins aren't installed. Formatting is prettier's job.
|
`@typescript-eslint` and `react-hooks` rules whose plugins aren't installed. Formatting is prettier's job.
|
||||||
|
|
||||||
### Bindings
|
|
||||||
|
|
||||||
`bindings/` and the manifests beside it — `binding.gyp`, `Cargo.toml`, `pyproject.toml`, `setup.py`,
|
|
||||||
`go.mod`, `Package.swift`, `Makefile`, `CMakeLists.txt` — are generated by `tree-sitter init` from the
|
|
||||||
`bindings` and `metadata` sections of `tree-sitter.json`, and `.gitattributes` marks them
|
|
||||||
`linguist-generated`. Do not edit them by hand: change `tree-sitter.json` and regenerate.
|
|
||||||
|
|
||||||
`tree-sitter init --update` only rewrites what it considers outdated, and a changed `version` or
|
|
||||||
`description` does not count, so the manifests keep the old values until they are deleted and `init` is run
|
|
||||||
again. It leaves `README.md`, `package.json` and `.gitignore` alone, which is why the Node binding's
|
|
||||||
`package.json` entries — `main`/`types`, the `.` export, `files`, `node-addon-api`, `node-gyp-build`, the
|
|
||||||
`install` script and the optional `tree-sitter` peer — are maintained here rather than generated.
|
|
||||||
|
|
||||||
Every binding was built and run on macOS: `npm install` plus `npm run binding-test`, `cargo test`,
|
|
||||||
`go test ./bindings/go/`, `pip install .` with a parse, `swift build`, and `make`. The Go binding needs a
|
|
||||||
`go.sum`, which `go mod tidy` writes and which is committed with the rest.
|
|
||||||
|
|
||||||
`src/scanner.c` compiles without warnings, and should stay that way: cc and clang warn about `&&` within
|
|
||||||
`||` (`-Wlogical-op-parentheses`), so a comparison chain written with both needs its `&&` groups
|
|
||||||
parenthesized.
|
|
||||||
|
|
||||||
### CI and releasing
|
|
||||||
|
|
||||||
`.github/workflows/ci.yml` runs on pull requests, and the release workflow calls it: the corpus tests, a
|
|
||||||
check that `npm run parser-generate` leaves `src/` unchanged, the Node binding on Linux, macOS and Windows,
|
|
||||||
and the Rust, Python, Go and Swift bindings.
|
|
||||||
|
|
||||||
`.github/workflows/release.yml` runs on every push to `main` but only releases when `package.json`'s version
|
|
||||||
differs from the previous commit's and no `v<version>` tag exists yet. Then it runs CI, `prebuildify` on
|
|
||||||
five runners (Linux x64 and arm64, macOS x64 and arm64, Windows x64), and a last job that tags `v<version>`,
|
|
||||||
creates the GitHub release with `tree-sitter-django.wasm` attached, and runs
|
|
||||||
`npm stage publish --provenance`. **A release is a version-bump commit on `main`**; no other push starts one.
|
|
||||||
|
|
||||||
**The workflow stages the publish; it does not publish.** `npm stage publish` hands npm the tarball and
|
|
||||||
holds it there, unavailable to install, until a maintainer runs `npm stage approve <stage-id>` and answers a
|
|
||||||
2FA prompt — proof of presence deferred rather than dropped, which is npm's answer to deprecating the tokens
|
|
||||||
that let a workflow publish unattended. The job summary prints the `view`/`download`/`approve`/`reject`
|
|
||||||
commands for the stage it made. Approving needs npm 12 (`npm install -g npm@^12`), which is also why the job
|
|
||||||
installs it: no runner image ships an npm that has the command.
|
|
||||||
|
|
||||||
Running the workflow by hand (`workflow_dispatch`) is the retry: it stages whatever version `package.json`
|
|
||||||
holds as long as `npm view` does not find it on the registry already, and it skips the tag and the release
|
|
||||||
when a previous attempt left them behind, replacing only the Wasm asset. So a run that tagged and then
|
|
||||||
failed to stage is finished by running it again, and a run against an already published version stops at the
|
|
||||||
version job. A version that is _staged_ and not yet approved is invisible to `npm view` while still
|
|
||||||
occupying npm's version index, so a second stage of it is an error rather than a no-op; the stage job asks
|
|
||||||
`npm stage list` first and skips straight to the approval summary when it finds one. That listing is
|
|
||||||
best-effort — a short-lived OIDC token may not run `npm stage` subcommands at all — and a failure there just
|
|
||||||
means the stage is attempted.
|
|
||||||
|
|
||||||
Releasing needs three things to line up:
|
|
||||||
|
|
||||||
- credentials to stage with: either a trusted publisher configured for this workflow
|
|
||||||
(`npm trust github --allow-stage-publish`), which needs no secret at all because npm exchanges the
|
|
||||||
workflow's OIDC token for one of its own, or the `NPM_TOKEN` secret as the fallback. Staging works with any
|
|
||||||
token type, so that token no longer needs — and should no longer have — the 2FA bypass an automation token
|
|
||||||
carries. Both the exchange and provenance need `id-token: write`, which the publish job already declares.
|
|
||||||
- **the version in `package.json` and in `tree-sitter.json`'s `metadata`**. The release trigger reads the
|
|
||||||
first; the second is compiled into `src/parser.c` as the language's version, so bumping one alone leaves
|
|
||||||
the parser disagreeing with the manifest.
|
|
||||||
- `npm run parser-generate` after that bump, committed with it, or CI's up-to-date check fails on a two-line
|
|
||||||
diff in `src/parser.c`.
|
|
||||||
|
|
||||||
The arm64 Linux runner (`ubuntu-24.04-arm`) is free for public repositories only. `tree-sitter build --wasm`
|
|
||||||
runs Emscripten through Docker, which the ubuntu runners provide.
|
|
||||||
|
|
||||||
**Windows needs a newer npm than its runner ships.** `windows-latest` is Windows Server 2025 **with Visual
|
|
||||||
Studio 2026**, and the node-gyp bundled with that image's npm (11.5.0) reads VS 18 as
|
|
||||||
`unknown version "undefined"` and then reports "Could not find any Visual Studio installation to use", so
|
|
||||||
`npm ci` fails in the install script. node-gyp learned VS 2026 in 12.1.0 and npm 12 bundles 13, which is why
|
|
||||||
both jobs that compile the addon there — CI's Node binding and the release's `prebuild` — install `npm@^12`
|
|
||||||
first. Pinning `windows-2022` instead would work, at the price of testing against a toolchain the image no
|
|
||||||
longer has. Installs of the published package never meet this: they unpack a prebuild and never run node-gyp.
|
|
||||||
|
|
||||||
**The npm package must carry its prebuilds**, or `npm install` runs `node-gyp-build`, finds nothing and
|
|
||||||
compiles, which fails on an image without `python3`, `make` and a compiler — `node:20-slim`, for instance.
|
|
||||||
0.1.0 was published by hand before the workflow existed and shipped none, which is what that image hit. The
|
|
||||||
`prebuild` jobs are what produce them, and `files` carries `prebuilds/**`.
|
|
||||||
|
|
||||||
`npm run prebuildify` passes `--napi --strip --tag-libc`. `--napi` makes one binary per platform that every
|
|
||||||
Node ABI can load, so the file needs no ABI tag and is named after the package. `--tag-libc` adds `glibc` or
|
|
||||||
`musl`: `node-gyp-build` treats a file with no libc tag as matching anything, so an Alpine install would
|
|
||||||
otherwise load a glibc binary and fail at run time; with the tag it compiles instead. Only glibc is built,
|
|
||||||
so musl installs need a toolchain.
|
|
||||||
|
|
||||||
`package.json` exports the Wasm build as `tree-sitter-django/tree-sitter-django.wasm`. An `exports` map
|
|
||||||
hides everything it does not name, so each published path — the queries, `grammar.js`, `src/scanner.c` —
|
|
||||||
needs its own entry.
|
|
||||||
|
|
||||||
### Stale parser library
|
### Stale parser library
|
||||||
|
|
||||||
tree-sitter caches the compiled parser in `~/.cache/tree-sitter/lib/django.*`, and it has served a stale
|
tree-sitter caches the compiled parser in `~/.cache/tree-sitter/lib/django.*`, and it has served a stale
|
||||||
@@ -139,20 +46,19 @@ argument, so `{% cycle 1as x %}` is the single token `1as` — an error, not `1`
|
|||||||
can never be made mandatory, so the separator is an explicit token and every rule is built from helpers
|
can never be made mandatory, so the separator is an explicit token and every rule is built from helpers
|
||||||
that place it:
|
that place it:
|
||||||
|
|
||||||
- `SEP` — `sym("_sep")`, the hidden rule `_sep: /[ \t\r\n]+/`, which a grammar extending this one writes as
|
- `SEP` — `/[ \t\r\n]+/`. Newlines included: Django matches tags with `re.DOTALL`, so tags may span lines.
|
||||||
`$._sep`. Newlines included: Django matches tags with `re.DOTALL`, so tags may span lines.
|
|
||||||
- `part(...)` — one tag part, taking the whitespace that separates it from the part before.
|
- `part(...)` — one tag part, taking the whitespace that separates it from the part before.
|
||||||
- `joined(first, ...rest)` — parts separated from _each other_, with no leading separator (`not in`).
|
- `joined(first, ...rest)` — parts separated from _each other_, with no leading separator (`not in`).
|
||||||
- `tag(name, ...args)` — `{%`, optional separator, tag name, args, optional separator, `%}`; tags may
|
- `block(tag, ...args)` — `{%`, optional separator, tag name, args, optional separator, `%}`; tags may
|
||||||
hug their delimiters (`{%cycle 1%}`).
|
hug their delimiters (`{%cycle 1%}`).
|
||||||
- `asVariable($)` — the `as name` clause. Every tag that takes one names the target `field("variable", …)`;
|
- `asVariable($)` — the `as name` clause. Every tag that takes one names the target `field("variable", …)`;
|
||||||
do not invent a second name for it.
|
do not invent a second name for it.
|
||||||
- `simpleTag($, name, args, kwargs)` — a tag registered with Django's `simple_tag`, which always accepts
|
- `simpleTag($, tag, args, kwargs)` — a tag registered with Django's `simple_tag`, which always accepts
|
||||||
positional filter expressions, then `name=value` keywords, then `as name`. `args`: `true` (`*args`), a
|
positional filter expressions, then `name=value` keywords, then `as name`. `args`: `true` (`*args`), a
|
||||||
count (at most N), or `false`. `kwargs`: `true` (`**kwargs`), `false`, or `{name: rule}` for a known
|
count (at most N), or `false`. `kwargs`: `true` (`**kwargs`), `false`, or `{name: rule}` for a known
|
||||||
signature. Put the Python signature in a comment above the call site.
|
signature. Put the Python signature in a comment above the call site.
|
||||||
- `arrangements(items)` — every ordered subset of `items`, so that a tag's options may be written in any
|
- `arrangements(items)` — every ordered subset of `items`, so that a tag's options may be written in any
|
||||||
order but never twice. Used by `translate_tag` and `include_tag`; keyword arguments are guarded by the scanner
|
order but never twice. Used by `translate` and `include`; keyword arguments are guarded by the scanner
|
||||||
instead. Grows as `Σ C(n,k)·k!` (65 for four names), which is
|
instead. Grows as `Σ C(n,k)·k!` (65 for four names), which is
|
||||||
why it is only used for signatures that name their arguments.
|
why it is only used for signatures that name their arguments.
|
||||||
- `wordAsValueRules(word)` / `wordAsValue($, word, continued)` — a tag's own keyword written where a value
|
- `wordAsValueRules(word)` / `wordAsValue($, word, continued)` — a tag's own keyword written where a value
|
||||||
@@ -179,84 +85,44 @@ Consequences worth knowing before editing a rule:
|
|||||||
table is built and discards the other parse outright, which is how a bare `{% if x is y %}` came to be
|
table is built and discards the other parse outright, which is how a bare `{% if x is y %}` came to be
|
||||||
an error.
|
an error.
|
||||||
|
|
||||||
### A tag group is a sequence of blocks
|
### A tag group is a sequence of clauses
|
||||||
|
|
||||||
Every group is split so that each tag that opens a body owns a node of its own:
|
Every group is split so that each tag that opens a body owns a node of its own:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
if_tag: ($) => startTag("if", part($.predicate)),
|
if_clause: ($) => seq(block("if", part($.predicate)), optional($.template)),
|
||||||
if_block: ($) => seq($.if_tag, optional($.template)),
|
|
||||||
endif_tag: ($) => endTag("endif"),
|
|
||||||
if_group: ($) =>
|
if_group: ($) =>
|
||||||
seq(
|
seq($.if_clause, repeat($.elif_clause), optional($.else_clause), block("endif")),
|
||||||
$.if_block,
|
|
||||||
repeat($.elif_block),
|
|
||||||
optional($.else_block),
|
|
||||||
choice($.endif_tag, alias($._missing_tag, $.missing_endif_tag)),
|
|
||||||
),
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**A block is complete without the closing tag, and that is the point.** While a template is being edited
|
**A clause is complete without the closing tag, and that is the point.** While a template is being edited
|
||||||
the closer usually is not there yet, and a group rule cannot be reduced without it — so `{% if a %}{% x %}`
|
the closer usually is not there yet, and a group rule cannot be reduced without it — so `{% if a %}{% x %}`
|
||||||
used to produce a top-level `ERROR` with the body's `template` parented to nothing that says which tag
|
used to produce a top-level `ERROR` with the body's `template` parented to nothing that says which tag
|
||||||
opened it. A block reduces anyway, so it survives error recovery and tooling can walk up from the cursor
|
opened it. A clause reduces anyway, so it survives error recovery and tooling can walk up from the cursor
|
||||||
to find the enclosing tag. That is what makes completion of `{% elif %}`, `{% else %}`, `{% empty %}` and
|
to find the enclosing tag. That is what makes completion of `{% elif %}`, `{% else %}`, `{% empty %}` and
|
||||||
the end tags possible.
|
the end tags possible.
|
||||||
|
|
||||||
**Every `{% %}` is a node of its own, named `<name>_tag`** after the tag's name as Django spells it: `if_tag`,
|
|
||||||
`elif_tag`, `endif_tag`, `block_tag`, `templatetag_tag`, `custom_tag`. A block is its
|
|
||||||
opening tag and a body; a group is its blocks and its end tag. A tag ends at `%}` and nothing can
|
|
||||||
extend it, so it reduces on whatever token follows — the end of input included — and a half-written
|
|
||||||
template still holds the last `{% for … %}` or `{% endif %}` typed as a whole node, not as loose tokens.
|
|
||||||
Stripping `_tag` gives the tag name; a new tag, or a tag group's new part, follows the same scheme.
|
|
||||||
|
|
||||||
A group's last child is its end block or, where the end tag is missing, a zero-width marker named for it
|
|
||||||
(`missing_endif_tag`; see the scanner section). So an unterminated group still reduces to a group node,
|
|
||||||
and a group's tag written where no open group can hold it is an `unexpected_tag` (see the load section
|
|
||||||
below), so only a body the grammar cannot read produces an `ERROR`.
|
|
||||||
|
|
||||||
Every tag is built from ten inline utility rules — `simpleTagOpen`/`simpleTagClose`,
|
|
||||||
`startTagOpen`/`startTagClose`,
|
|
||||||
`followTagOpen`/`followTagClose`, `repeatTagOpen`/`repeatTagClose`, `endTagOpen`/`endTagClose` —
|
|
||||||
through the helpers `tag` (a tag outside any group, from `simpleTagOpen`/`simpleTagClose`), `startTag`, `followTag` (a middle tag a group
|
|
||||||
holds at most once: `else`, `empty`, `plural`), `repeatTag` (one it may repeat: `elif`) and `endTag`.
|
|
||||||
They are inline rules rather than JS helpers so that a grammar extending this one can use them. **Every
|
|
||||||
tag must begin with one of the opens**, one an extending grammar adds included: the token they read the
|
|
||||||
tag's name with is valid wherever a tag's name is and the scanner always returns it, so a tag written from a bare `"{%"` never matches: its name is read as a `custom_tag` instead,
|
|
||||||
with no error to show for it. Choose `followTag` or `repeatTag` by what the grammar allows, because the
|
|
||||||
scanner trusts it: a tag marked once-only that can in fact repeat is an `unexpected_tag` from its
|
|
||||||
second use on, and one marked repeatable that cannot is never flagged when repeated.
|
|
||||||
|
|
||||||
The names themselves need no hand-maintained list either: in the generated `src/node-types.json`, a group's
|
The names themselves need no hand-maintained list either: in the generated `src/node-types.json`, a group's
|
||||||
`children` are its block types and its end tag, and a block's children include its opening tag, so
|
`children` are its clause types and its own `tag:` field holds the end tag, so the candidates for a group
|
||||||
the candidates for a group are its end tag plus the opening tag of each block it can hold. For
|
are its `tag:` plus the `tag:` of each clause it can hold. For `if_group` that is `endif` from the group and
|
||||||
`if_group` that is `endif_tag` from the group and `if_tag`, `elif_tag`, `else_tag` from its three
|
`if`, `elif`, `else` from its three clauses. Going the other way — from a clause the cursor sits in to the
|
||||||
blocks. Going the other way — from a block the cursor sits in to the
|
groups that can hold it — is the same table read backwards, which is what an unterminated tag needs, since
|
||||||
groups that can hold it — is the same table read backwards, which is what a block needs when error
|
the group node does not exist yet.
|
||||||
recovery has left it without its group.
|
|
||||||
|
|
||||||
Do not reach for lookahead to solve that instead: `ts_language_next_state` follows only the shift on `{%`,
|
Do not reach for lookahead to solve that instead: `ts_language_next_state` follows only the shift on `{%`,
|
||||||
which lands in the "a tag starts here" state no matter how the tree is shaped.
|
which lands in the "a tag starts here" state no matter how the tree is shaped.
|
||||||
|
|
||||||
`else_block` is shared by `if_group` and `ifchanged_group`. `comment_block` and `verbatim_block` hold raw
|
`else_clause` is shared by `if_group` and `ifchanged_group`. `comment_group` and `verbatim_group` have no
|
||||||
scanner text that admits no tags. `blocktranslate_group` has one block per spelling, `blocktrans_block` and
|
clause — their bodies are raw scanner text that admits no tags — and neither does `blocktranslate_group`,
|
||||||
`blocktranslate_block`, because each must be closed by its own end tag; the counted form nests a
|
whose body is `_translate_body`.
|
||||||
`plural_block` inside it, since `{% plural %}` is only valid after `count`. The block has to know which
|
|
||||||
form its opening tag was, so `blocktransRules` builds each as a hidden rule (`_blocktrans_tag`,
|
|
||||||
`_blocktrans_count_tag`) and aliases both to the one visible `blocktrans_tag` where the block uses
|
|
||||||
it. Their bodies are
|
|
||||||
`_translate_body`, not `template`, which is why these four blocks need no `conflicts` entry — the rule
|
|
||||||
below is about a body that can itself start with `{%`.
|
|
||||||
|
|
||||||
**Every block needs a `conflicts` entry.** The generator offers a left associativity instead; taking it is
|
**Every clause needs a `conflicts` entry.** The generator offers a left associativity instead; taking it is
|
||||||
what broke `{% for %}` in `06aa870`, where `prec.left` resolved the shift/reduce on `{%` statically and
|
what broke `{% for %}` in `06aa870`, where `prec.left` resolved the shift/reduce on `{%` statically and
|
||||||
silently discarded the parse in which the body continues, so every tag inside a loop became an `ERROR`.
|
silently discarded the parse in which the body continues, so every tag inside a loop became an `ERROR`.
|
||||||
|
|
||||||
Sharing the blocks also made the table markedly smaller — 7,200 states and a 515KB library became 5,150
|
Sharing the clauses also made the table markedly smaller — 7,200 states and a 515KB library became 5,150
|
||||||
and 383KB — for the same reason hoisting `blocktranslate`'s pieces into hidden rules did: the automaton
|
and 383KB — for the same reason hoisting `blocktranslate`'s pieces into hidden rules did: the automaton
|
||||||
stops duplicating the body states in every group's inline context. Giving every `{% %}` its own `_tag`
|
stops duplicating the body states in every group's inline context.
|
||||||
rule shrank it again, from 1,999 states to 1,818, by the same mechanism. The group stack's tokens (see the
|
|
||||||
scanner section) cost 247, to 3,304.
|
|
||||||
|
|
||||||
### Filter pipes differ by context
|
### Filter pipes differ by context
|
||||||
|
|
||||||
@@ -272,10 +138,7 @@ arity, or whether a tag is a block tag. Two fallback rules accept them:
|
|||||||
|
|
||||||
- `custom_tag` — `simpleTag($, $.identifier)`, i.e. what `simple_tag`/`inclusion_tag` accept, which is how
|
- `custom_tag` — `simpleTag($, $.identifier)`, i.e. what `simple_tag`/`inclusion_tag` accept, which is how
|
||||||
a tag is registered unless it needs the parser itself.
|
a tag is registered unless it needs the parser itself.
|
||||||
- `_custom_filter`, the last alternative of `filter`, whose name is `$.identifier` rather than one of the
|
- the last alternative of `filter`, whose name is `$.identifier` rather than one of the builtin literals.
|
||||||
builtin literals. Hidden, so the tree is what an inline alternative would give, but named so that a
|
|
||||||
grammar extending this one can filter it out of `filter`'s `members` the way it can `custom_tag` — see
|
|
||||||
the extension section in `README.md`.
|
|
||||||
|
|
||||||
**A name that only exists inside a tag group has to be reserved instead.** `endif`, `else`, `empty` and
|
**A name that only exists inside a tag group has to be reserved instead.** `endif`, `else`, `empty` and
|
||||||
the rest are tokens only in the state their group opens, so where a tag is named the lexer reads them as an
|
the rest are tokens only in the state their group opens, so where a tag is named the lexer reads them as an
|
||||||
@@ -285,55 +148,6 @@ listed in `NAMES_INSIDE_A_TAG_GROUP` and applied through the `tag_name` reserved
|
|||||||
wraps, so wrapping the whole rule would un-reserve `as` and reject `{% mytag endif %}`. Adding a tag group
|
wraps, so wrapping the whole rule would un-reserve `as` and reject `{% mytag endif %}`. Adding a tag group
|
||||||
with a new part or end tag means adding its name there too.
|
with a new part or end tag means adding its name there too.
|
||||||
|
|
||||||
**The same names are what `unexpected_tag` accepts.** Once reserved, a group's tag written where no open
|
|
||||||
group can hold it — `{% endif %}` with nothing open, `{% else %}` in a `{% for %}` — used to be an `ERROR`,
|
|
||||||
and error recovery placed it badly: every tag starts with `{%` and the read token, which the parser has
|
|
||||||
already accepted when the name turns out to be wrong, so recovery rewinds to just after them and folds the
|
|
||||||
stray tag into whichever tag comes next, which then holds the `ERROR`. `unexpected_tag` takes any of
|
|
||||||
`NAMES_INSIDE_A_TAG_GROUP` with loose arguments, so there is nothing to recover; `prec.dynamic(-2)`, or `-4`, keeps it
|
|
||||||
from displacing a tag the group does take, and `queries/errors.scm` reports it as
|
|
||||||
`@error.unexpected_tag`. It added 31 states and no `conflicts` entry.
|
|
||||||
|
|
||||||
**Words a tag does not take are an `unexpected_argument` inside it.** Every close utility accepts one
|
|
||||||
before its scanner token, so `{% else x %}` stays the `else` of its group, `{% endif junk %}` still closes
|
|
||||||
its `if` (it used to leave the whole file an `ERROR`), and `{% static "a.css" "b.css" %}` is a `static_tag`.
|
|
||||||
The node is a run of hidden `_unexpected_word`s, and three details make it work:
|
|
||||||
|
|
||||||
- **Lexical precedence -1.** A loose word is `token(prec(-1, /(?:[^\s%}]|\}[^\s%}])+/))`, which never holds `}}`:
|
|
||||||
lexer states are shared between parse states, so the token is tried inside `{{ }}` too, and after
|
|
||||||
`{{ x| ` it once swallowed the closing braces and left recovery nothing to close the variable with. Tree-sitter weighs lexical
|
|
||||||
precedence before match length, so a token an argument really takes wins wherever one is valid
|
|
||||||
(`b|upper` stays a filtered value) and a loose word only matches where nothing else can.
|
|
||||||
- **Identifiers are words too.** Wherever a keyword is valid — after `{% for a in b`, where `reversed` may
|
|
||||||
follow, or after `as`, `only`, `noop`, `silent` — tree-sitter lexes every word as an `identifier` to
|
|
||||||
check for the keyword, and the loose-word token never gets a turn. So a word may also be an
|
|
||||||
`identifier`, aliased to an anonymous `unexpected_word` so `queries/locals.scm` does not count it as a
|
|
||||||
reference, with whatever touches it (`a=2`, `x.y|upper`, `"z"|lower:"q"`) as an immediate tail.
|
|
||||||
- **-1 of dynamic precedence per word**, not per node, so a reading that flags more words than it must
|
|
||||||
always loses: `{% cycle a b as x silent zqx %}` flags `zqx`, not everything after `a`. `unexpected_tag`
|
|
||||||
costs -2 or -4 so that a misused tag its group does take beats reading it as a stray.
|
|
||||||
|
|
||||||
A tag with a known keyword signature (`simpleTag` given names, so far only `csp_nonce_attr`) needs one more
|
|
||||||
piece: the scanner's `_kwarg_name` accepts any name followed by `=` and commits the parser to a keyword
|
|
||||||
argument before the name is checked, so `{% csp_nonce_attr other="b" %}` would be an `ERROR`. `simpleTag`
|
|
||||||
offers `_unexpected_keyword` — an identifier and its tail, aliased to `unexpected_argument` — beside the
|
|
||||||
names it knows.
|
|
||||||
|
|
||||||
A separator after any argument can now also start stray words, so this needs `conflicts` entries for
|
|
||||||
`unexpected_argument`, `predicate`, `_translate_option`, and `_unexpected_word` with `variable_attribute`,
|
|
||||||
`resetcycle_tag` and `library`. It took the table from 3,363 states to 4,913 and the Wasm build from 251KB to
|
|
||||||
323KB. Two consequences: a repeat the scanner refuses — `{% with a=1 a=2 %}`, `{% blocktrans trimmed trimmed %}`
|
|
||||||
— is reported as an unexpected argument rather than an `ERROR`; and a stray **reserved** word is still an
|
|
||||||
`ERROR`, since `not`, `if`, `in`, `is`, `as`, `for` and `from` can never be an identifier:
|
|
||||||
`{% trans "hi" as x as y %}` errors on the second `as`. A tag missing a required argument, such as
|
|
||||||
`{% with a = 1 %}`, is an `ERROR` too; `unexpected_argument` only takes words after a tag that is otherwise
|
|
||||||
complete.
|
|
||||||
|
|
||||||
Where several tags share a name the group holds only once — `{% if %}{% else %}{% else %}{% else %}` — reading
|
|
||||||
any of them as the stray parses, so the ties are broken by dynamic precedence: `unexpected_tag` is -2 when
|
|
||||||
`_group_held` confirms the innermost group already holds the name and -4 otherwise, so each tag flagged
|
|
||||||
before its time costs one more, and the first still opens the block however many follow.
|
|
||||||
|
|
||||||
**Builtin names must stay keyword-extractable, or the fallbacks swallow them.** `word: $.identifier` turns
|
**Builtin names must stay keyword-extractable, or the fallbacks swallow them.** `word: $.identifier` turns
|
||||||
each builtin's name into its own token, which the lexer prefers wherever it is valid, so a builtin commits
|
each builtin's name into its own token, which the lexer prefers wherever it is valid, so a builtin commits
|
||||||
to its own alternative and its argument rules still apply. This is why a filter's name and its `:` are
|
to its own alternative and its argument rules still apply. This is why a filter's name and its `:` are
|
||||||
@@ -377,12 +191,12 @@ README nothing checks at all. The library-contents differential below, run again
|
|||||||
|
|
||||||
### External scanner (`src/scanner.c`)
|
### External scanner (`src/scanner.c`)
|
||||||
|
|
||||||
Twenty external tokens, for the constraints a context-free grammar cannot express:
|
Twelve external tokens, for the constraints a context-free grammar cannot express:
|
||||||
|
|
||||||
- `push_block`/`push_partial`/`push_verbatim` and the matching `pop_*` — the names in
|
- `push_block`/`push_partial`/`push_verbatim` and the matching `pop_*` — name matching for
|
||||||
`{% block a %}…{% endblock a %}`. A push token reads the name into `pending_name`, which the group takes
|
`{% block a %}…{% endblock a %}`. They share **one** stack of `{kind, name}` entries, not one stack per
|
||||||
when `_group_open_tag_push` pushes it; a pop token checks the written name, or its absence, against the
|
kind: the grammar already guarantees nesting, so only the innermost open tag can be closed, and there is
|
||||||
innermost open group, the only one the grammar lets it close, and `_group_close` then pops it.
|
never a second candidate name to try. Serialized as `<kind><name> ` per entry (`tag_kind_chars`).
|
||||||
- `verbatim_content`, `comment_content` — raw text up to the matching close tag.
|
- `verbatim_content`, `comment_content` — raw text up to the matching close tag.
|
||||||
- `_tag_open`, `_bt_option`, `_kwarg_name` — what a tag has already been given, so that a repeated
|
- `_tag_open`, `_bt_option`, `_kwarg_name` — what a tag has already been given, so that a repeated
|
||||||
argument is refused: `_bt_option` for `{% blocktranslate %}`'s five options, `_kwarg_name` for `name=value`
|
argument is refused: `_bt_option` for `{% blocktranslate %}`'s five options, `_kwarg_name` for `name=value`
|
||||||
@@ -394,59 +208,9 @@ Twenty external tokens, for the constraints a context-free grammar cannot expres
|
|||||||
flags, not a stack, because the tag cannot nest: its body admits no tags. It lives outside the
|
flags, not a stack, because the tag cannot nest: its body admits no tags. It lives outside the
|
||||||
`stack`/`error` union, is cleared in both branches of `reset_scanner`, and is serialized after the
|
`stack`/`error` union, is cleared in both branches of `reset_scanner`, and is serialized after the
|
||||||
status character, so a GLR stack split copies it like everything else.
|
status character, so a GLR stack split copies it like everything else.
|
||||||
- `_group_open_tag_read`, `_group_open_tag_push`, `_group_follow`, `_group_repeat`, `_group_close`, `_group_held` —
|
|
||||||
the stack
|
|
||||||
of open groups, which the scanner keeps **without knowing any group by name**, so a grammar extending this
|
|
||||||
one gets it for its own groups. The read token sits right after `{%` in every tag, always returns, and
|
|
||||||
reads the tag's name into `read_word`. The other four sit right before `%}` and check that it follows:
|
|
||||||
push opens a group expecting `"end"` + `read_word` (every Django end tag is spelled that way), follow
|
|
||||||
records a middle tag the innermost group may hold only once, repeat records nothing, and close pops the
|
|
||||||
innermost group once `read_word` is what it expects. `_group_held` belongs to `unexpected_tag` (see the load section) and returns only when
|
|
||||||
the innermost group already holds a tag named `read_word`. Reading `count` (`_bt_option`) marks the group about
|
|
||||||
to be pushed as waiting for `plural`, which its follow clears. An entry is
|
|
||||||
`{expected, name, middles, awaits_plural}`, serialized as `expected:name:middles:flag` and a newline per
|
|
||||||
entry; entries hold whole names, so serializing checks `TREE_SITTER_SERIALIZATION_BUFFER_SIZE` and goes to
|
|
||||||
the error state rather than overrun it. Push and follow before `%}` cost 247 states over the table-driven
|
|
||||||
scanner (3,057 to 3,304), because argument-final states stop being shared with tags where the token is not
|
|
||||||
valid; after `%}`, where each tag's states are its own, saved only 15.
|
|
||||||
- `_missing_tag` — the marker where a group's required tag block is missing, aliased at each use to
|
|
||||||
`missing_endX_tag` or `missing_plural_tag` (`MISSING_TAGS`). It is placed only at the end of input;
|
|
||||||
before the end tag of a group enclosing the innermost one; before an `endblock`/`endpartialdef` naming a
|
|
||||||
block further out; or before a second `plural`, since a blocktranslate body holds no tag that could take it.
|
|
||||||
Any other tag is taken to be the innermost group's, as Django's parser takes it — a middle tag it has not
|
|
||||||
held yet, and a second of one it holds only once, which is an `unexpected_tag` inside it. Marking the
|
|
||||||
group closed before a second `else` was tried and dropped: inside `{% block %}`, where most template code
|
|
||||||
sits, there is always an enclosing group to hand the `else` to, so the inner group's own end tag became a
|
|
||||||
stray instead. A counted blocktranslate is missing its
|
|
||||||
plural before anything but `plural`. The marker closes the group as its end tag would (or records the
|
|
||||||
plural), the group reduces with no `ERROR`, and `queries/errors.scm` reports it. Tags in a raw body are
|
|
||||||
not read: the marker tells the body is raw from `verbatim_content`/`comment_content` being valid, and only
|
|
||||||
the end of input counts there. **It is one token aliased per group, never a token per group**: tree-sitter
|
|
||||||
does not merge parse states whose valid external tokens differ, so a token per group cloned every body
|
|
||||||
state for each kind of group and took the table from 1,818 states to 17,664. A supertype would be the
|
|
||||||
natural way to match every marker, but the generator silently drops one whose members are aliases, so
|
|
||||||
`errors.scm` lists them.
|
|
||||||
|
|
||||||
What a stack that knows no group cannot tell: a middle tag of an enclosing group that the innermost group
|
|
||||||
has never held — `{% if a %}{% for x in y %}{% else %}` — is an `ERROR`, not a marker. Learning each
|
|
||||||
group's middle tags as they appear was tried first and put false markers on valid nesting such as
|
|
||||||
`{% if %}…{% else %}{% if %}…{% else %}`, because the outer group, having held an `else`, claimed the
|
|
||||||
inner one's.
|
|
||||||
|
|
||||||
- `_text_brace` — a single `{` that is text although the content regex cannot tell: before `{%` or `{#`,
|
|
||||||
and at the end of input. Django splits a template with `({%.*?%}|{{.*?}}|{#.*?#})`, so a `{` is text
|
|
||||||
unless one of those starts at it; `{{{` is not a text brace, since `{{` starts a variable at its first
|
|
||||||
brace. `content` is a right-associative run of `_text` and `_text_brace`, so it stays one node. Inside a
|
|
||||||
group's body the missing-tag check reads past `{` first, so it scans the brace itself
|
|
||||||
(`scan_text_brace_rest`) rather than give up the position.
|
|
||||||
- `_missing_variable_close` — the marker where a variable's `}}` is missing, aliased to
|
|
||||||
`missing_variable_close`. It is placed only where the variable cannot go on — at the end of input, or
|
|
||||||
before a `}` that is not `}}`, a `%` or a `{` — so `{{ hello }{% if x %}` closes the variable, reads the
|
|
||||||
stray `}` as text and parses the `if` normally, where error recovery used to take the rest of the file.
|
|
||||||
It is valid only after a variable's value, never where `content` is. It added 18 states.
|
|
||||||
- `matcher_error` — used by no rule; returned only if the scanner reaches an error state.
|
- `matcher_error` — used by no rule; returned only if the scanner reaches an error state.
|
||||||
|
|
||||||
`check_space()` defines whitespace for the scanner and **must stay in sync with `_sep`**, because the
|
`check_space()` defines whitespace for the scanner and **must stay in sync with `SEP`**, because the
|
||||||
scanner skips whitespace itself while matching names.
|
scanner skips whitespace itself while matching names.
|
||||||
|
|
||||||
Prefer the grammar over the scanner. A useful test: does the constraint change how the input _parses_?
|
Prefer the grammar over the scanner. A useful test: does the constraint change how the input _parses_?
|
||||||
@@ -469,26 +233,19 @@ Zero-width guards carry one hazard: `recover_with_missing` can supply one withou
|
|||||||
during tree-sitter's mark-everything-valid recovery pass, so new guards go **below** it — and above the
|
during tree-sitter's mark-everything-valid recovery pass, so new guards go **below** it — and above the
|
||||||
whitespace loop, which skips the separator the grammar still has to match. A guard must also never be valid
|
whitespace loop, which skips the separator the grammar still has to match. A guard must also never be valid
|
||||||
where `content` is: a zero-width token at a content boundary preempts the internal lexer and `content` stops
|
where `content` is: a zero-width token at a content boundary preempts the internal lexer and `content` stops
|
||||||
matching. `_missing_tag` is the one exception, and is safe only because it returns a token solely at the end
|
matching.
|
||||||
of input or at `{%`, where `content` cannot match. It is scanned above the raw-text scanners, which find
|
|
||||||
nothing at the end of an empty body.
|
|
||||||
|
|
||||||
The group tokens were checked against that hazard with malformed groups — a missing predicate, junk before
|
|
||||||
`%}`, in an end tag, in `{% else %}` and in `{% plural %}`, and a mismatched block name. Recovery never
|
|
||||||
inserted one of them as `MISSING`, and the stack never fell out of step with the parser: later groups still
|
|
||||||
got the right markers. Junk inside an end tag does leave the whole file an `ERROR`.
|
|
||||||
|
|
||||||
### Queries
|
### Queries
|
||||||
|
|
||||||
`queries/highlights.scm` lists tag and filter names explicitly, so adding either to the grammar means
|
`queries/highlights.scm` lists tag and filter names explicitly, so adding either to the grammar means
|
||||||
adding it there too; filter names appear there without their colon. A name the grammar does not know is
|
adding it there too; filter names appear there without their colon. A name the grammar does not know is
|
||||||
captured through its field instead (`(filter filter_name: (identifier))`, `(custom_tag tag_name: (identifier))`).
|
captured through its field instead (`(filter name: (identifier))`, `(custom_tag tag: (identifier))`).
|
||||||
|
|
||||||
`queries/libraries.scm` is not a query editors run themselves; it is data for a linter, and every tag or
|
`queries/libraries.scm` is not a query editors run themselves; it is data for a linter, and every tag or
|
||||||
filter added from a library belongs in it. `queries/locals.scm` relies on the `variable:` field to tell a
|
filter added from a library belongs in it. `queries/locals.scm` relies on the `variable:` field to tell a
|
||||||
binding from a reference — another reason to keep `asVariable` uniform. `{% blocktranslate %}`'s `asvar`
|
binding from a reference — another reason to keep `asVariable` uniform. `{% blocktranslate %}`'s `asvar`
|
||||||
target carries an `asvar:` field instead, because it is written inside the tag but assigned outside it:
|
target carries an `asvar:` field instead, because it is written inside the tag but assigned outside it:
|
||||||
the scope on `blocktrans_block` / `blocktranslate_block` confines the `with` and `count` bindings, and would swallow `asvar`
|
the scope on `blocktranslate_group` confines the `with` and `count` bindings, and would swallow `asvar`
|
||||||
too if it were spelled the same way. `queries/exports.scm` names it for a tool to
|
too if it were spelled the same way. `queries/exports.scm` names it for a tool to
|
||||||
bind in the scope around the block, which a locals query cannot do: it places a definition in the innermost
|
bind in the scope around the block, which a locals query cannot do: it places a definition in the innermost
|
||||||
scope containing it and offers no way out again.
|
scope containing it and offers no way out again.
|
||||||
@@ -498,24 +255,17 @@ scope containing it and offers no way out again.
|
|||||||
`{% if a %}{% now "Y" as n %}{% endif %}{{ n }}` may reach `{{ n }}` with nothing bound. A locals query
|
`{% if a %}{% now "Y" as n %}{% endif %}{{ n }}` may reach `{{ n }}` with nothing bound. A locals query
|
||||||
cannot: it matches a reference to the definition whose scope contains it and has no notion of a path not
|
cannot: it matches a reference to the definition whose scope contains it and has no notion of a path not
|
||||||
taken. A group is exhaustive iff it has a `@conditional.default`, so each pattern captures the group
|
taken. A group is exhaustive iff it has a `@conditional.default`, so each pattern captures the group
|
||||||
alongside one of its parts and a tool needs no list of which block belongs to which group. Adding a tag
|
alongside one of its parts and a tool needs no list of which clause belongs to which group. Adding a tag
|
||||||
group whose body may be skipped means adding it there — `{% cache %}` is the non-obvious one, since a
|
group whose body may be skipped means adding it there — `{% cache %}` is the non-obvious one, since a
|
||||||
cache hit skips the body outright and `CacheNode` pushes no context.
|
cache hit skips the body outright and `CacheNode` pushes no context.
|
||||||
|
|
||||||
A branch that is also a `@local.scope` confines its bindings whichever way the branch goes, which is why
|
A branch that is also a `@local.scope` confines its bindings whichever way the branch goes, which is why
|
||||||
`{% for %}` is inert for that check: `ForNode` renders `nodelist_empty` **inside** the same
|
`{% for %}` is inert for that check: `ForNode` renders `nodelist_empty` **inside** the same
|
||||||
`context.push()` as the loop body, so `empty_block` is a scope alongside `for_block`.
|
`context.push()` as the loop body, so `empty_clause` is a scope alongside `for_clause`.
|
||||||
|
|
||||||
`queries/errors.scm` collects what an editor should report: `(ERROR)` as `@error.syntax`, `(MISSING)` as
|
|
||||||
`@error.missing`, every missing-tag marker as `@error.missing_tag`, `unexpected_tag` and
|
|
||||||
`unexpected_argument` as `@error.unexpected_tag` and `@error.unexpected_argument`, and
|
|
||||||
`missing_variable_close` as `@error.missing_variable_close`. A tree holding only markers has
|
|
||||||
no `has_error`, so a tool that checks that flag alone misses them. Adding a tag group means adding its
|
|
||||||
marker there, since no supertype matches them all.
|
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
Corpus tests live in `test/corpus/*.txt`, one file per tag, and `missing.txt` for the missing-tag markers.
|
Corpus tests live in `test/corpus/*.txt`, one file per tag.
|
||||||
|
|
||||||
- A test whose header carries `:error` asserts only that the parse fails. Prefer it for syntax-error cases
|
- A test whose header carries `:error` asserts only that the parse fails. Prefer it for syntax-error cases
|
||||||
over pinning an error-recovery tree, which is brittle.
|
over pinning an error-recovery tree, which is brittle.
|
||||||
@@ -527,8 +277,8 @@ Corpus tests live in `test/corpus/*.txt`, one file per tag, and `missing.txt` fo
|
|||||||
|
|
||||||
### Checking against Django itself
|
### Checking against Django itself
|
||||||
|
|
||||||
`Pipfile.lock` pins Django (`Pipfile` itself says `django = "*"`) so the grammar can be diffed against the
|
The `Pipfile` pins Django so the grammar can be diffed against the real implementation instead of against
|
||||||
real implementation instead of against documentation or memory. Both checks are worth repeating whenever tags, filters or literals change:
|
documentation or memory. Both checks are worth repeating whenever tags, filters or literals change:
|
||||||
|
|
||||||
- **Builtin parity** — enumerate `Engine.default_builtins`, then compare `register.tags` and
|
- **Builtin parity** — enumerate `Engine.default_builtins`, then compare `register.tags` and
|
||||||
`register.filters` against `grammar.js`. For filters also compare argument arity via
|
`register.filters` against `grammar.js`. For filters also compare argument arity via
|
||||||
@@ -552,11 +302,7 @@ rule it states. Anything added here that fits that rule belongs there too; anyth
|
|||||||
unavoidable limitation, or a case where this grammar is the more permissive one — stays here.
|
unavoidable limitation, or a case where this grammar is the more permissive one — stays here.
|
||||||
|
|
||||||
- Django has no number token: `[\w.]+` is one lexeme and `int()`/`float()` decides whether it is a literal,
|
- Django has no number token: `[\w.]+` is one lexeme and `int()`/`float()` decides whether it is a literal,
|
||||||
so `1a`, `1e`, `0x1f`, `1.2.3`, `1__0` and `1.` are variable _lookups_ there and errors here. `1.` is the
|
so `1a`, `1e`, `0x1f`, `1.2.3`, `1__0` and `1.` are variable _lookups_ there and errors here.
|
||||||
one that needs care: `Variable` calls `float()` and then rejects what it parsed if the last character is
|
|
||||||
a dot (`# "2." is invalid`), so a trailing dot is a number only with an exponent after it — `1.e5` is a
|
|
||||||
float and `1.` is not. The `number` regex is spelled to say that, and `test/corpus/template_variable.txt`
|
|
||||||
pins all three.
|
|
||||||
- Django has no boolean or `None` token either. `True`, `False` and `None` are lookups, which resolve
|
- Django has no boolean or `None` token either. `True`, `False` and `None` are lookups, which resolve
|
||||||
because `BaseContext._reset_dicts` seeds every context with `{"True": True, "False": False, "None": None}`.
|
because `BaseContext._reset_dicts` seeds every context with `{"True": True, "False": False, "None": None}`.
|
||||||
They are `boolean` and `none` literals here, so that a tool reading `queries/locals.scm` does not count
|
They are `boolean` and `none` literals here, so that a tool reading `queries/locals.scm` does not count
|
||||||
@@ -564,12 +310,12 @@ unavoidable limitation, or a case where this grammar is the more permissive one
|
|||||||
binds an `identifier`, because the keyword is not valid where a binding name is — but `{{ True.x }}` is
|
binds an `identifier`, because the keyword is not valid where a binding name is — but `{{ True.x }}` is
|
||||||
an error here and an ordinary two-part lookup in Django, which renders `string_if_invalid`.
|
an error here and an ordinary two-part lookup in Django, which renders `string_if_invalid`.
|
||||||
- A `with` binding written twice (`{% with a=1 a=2 %}`, and the same in `{% include %}` and
|
- A `with` binding written twice (`{% with a=1 a=2 %}`, and the same in `{% include %}` and
|
||||||
`{% blocktranslate %}`) is reported here, as an `unexpected_argument`, and not in Django, where
|
`{% blocktranslate %}`) is an error here and not in Django, where `token_kwargs` builds a dict and the
|
||||||
`token_kwargs` builds a dict and the later value wins. It has no use, so it is treated as the mistake it almost certainly is.
|
later value wins. It has no use, so it is treated as the mistake it almost certainly is.
|
||||||
- `{% csp_nonce_attr "a" media="b" %}` is accepted, matching Django, which only rejects it at render time.
|
- `{% csp_nonce_attr "a" media="b" %}` is accepted, matching Django, which only rejects it at render time.
|
||||||
- A misspelled tag or filter cannot be caught: `{{ x|lenght }}` is indistinguishable from a filter some
|
- A misspelled tag or filter cannot be caught: `{{ x|lenght }}` is indistinguishable from a filter some
|
||||||
library registered. Cross-referencing names against `{% load %}` needs the project's Python, so it
|
library registered. Cross-referencing names against `{% load %}` needs the project's Python, so it
|
||||||
belongs in a linter; the `load_tag` rule already parses the library and `from` names for one to use.
|
belongs in a linter; the `load` rule already parses the library and `from` names for one to use.
|
||||||
- `{% mytag %}…{% endmytag %}` parses as two sibling `custom_tag`s. Nesting them would mean guessing that
|
- `{% mytag %}…{% endmytag %}` parses as two sibling `custom_tag`s. Nesting them would mean guessing that
|
||||||
an unknown tag is a block tag.
|
an unknown tag is a block tag.
|
||||||
- A custom tag's contents are only assumed to be the `simple_tag` shape. `@register.tag` receives the raw
|
- A custom tag's contents are only assumed to be the `simple_tag` shape. `@register.tag` receives the raw
|
||||||
@@ -578,7 +324,7 @@ unavoidable limitation, or a case where this grammar is the more permissive one
|
|||||||
redefines `length` with a different arity gets a false error here.
|
redefines `length` with a different arity gets a false error here.
|
||||||
- Django's `static` tags ignore what follows their argument: `StaticNode.handle_token` looks for `as` two
|
- Django's `static` tags ignore what follows their argument: `StaticNode.handle_token` looks for `as` two
|
||||||
bits from the end, so `{% static "a" junk %}` and `{% static "a" as u v %}` are accepted there and
|
bits from the end, so `{% static "a" junk %}` and `{% static "a" as u v %}` are accepted there and
|
||||||
reported here as an `unexpected_argument`, and `PrefixNode.handle_token` raises `IndexError` rather than `TemplateSyntaxError` on
|
rejected here, and `PrefixNode.handle_token` raises `IndexError` rather than `TemplateSyntaxError` on
|
||||||
`{% get_static_prefix as %}`.
|
`{% get_static_prefix as %}`.
|
||||||
- Django's `{% cache %}` takes its fragment name as the raw word in that position and finds the cache to
|
- Django's `{% cache %}` takes its fragment name as the raw word in that position and finds the cache to
|
||||||
use by testing whether the last word starts with `using=`, and only when something precedes it. So
|
use by testing whether the last word starts with `using=`, and only when something precedes it. So
|
||||||
@@ -587,12 +333,3 @@ unavoidable limitation, or a case where this grammar is the more permissive one
|
|||||||
name. All three are errors here.
|
name. All three are errors here.
|
||||||
- `partial`/`partialdef` are Django builtins as of Django 6; `elif`/`else`/`empty` are modelled as parts of
|
- `partial`/`partialdef` are Django builtins as of Django 6; `elif`/`else`/`empty` are modelled as parts of
|
||||||
their enclosing tag rather than as separate tags.
|
their enclosing tag rather than as separate tags.
|
||||||
- An unterminated group parses here and raises `TemplateSyntaxError` in Django: `{% if a %}x`, or a
|
|
||||||
`{% for %}` closed while an `{% if %}` inside it is still open, holds a `missing_endif_tag` marker
|
|
||||||
where the end tag belongs. The marker is the error, reported through `queries/errors.scm`; a check
|
|
||||||
for `ERROR` nodes alone accepts the tree.
|
|
||||||
- A `{{` that does not close is text in Django, whose lexer only takes a variable written `{{ … }}` on one
|
|
||||||
line, so `{{ hello }` renders as written. Here it is a `template_variable` closed by a
|
|
||||||
`missing_variable_close` marker, reported through `queries/errors.scm`, since a half-written variable is
|
|
||||||
what it almost always is. The same lexer makes `{{ hello\n}}` text too, which this grammar accepts as a
|
|
||||||
variable, because its separators allow newlines.
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.13)
|
|
||||||
|
|
||||||
project(tree-sitter-django
|
|
||||||
VERSION "0.1.0"
|
|
||||||
DESCRIPTION "Django grammar for tree-sitter"
|
|
||||||
HOMEPAGE_URL "https://github.com/danhanson/tree-sitter-django"
|
|
||||||
LANGUAGES C)
|
|
||||||
|
|
||||||
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
|
|
||||||
option(TREE_SITTER_REUSE_ALLOCATOR "Reuse the library allocator" OFF)
|
|
||||||
|
|
||||||
set(TREE_SITTER_ABI_VERSION 15 CACHE STRING "Tree-sitter ABI version")
|
|
||||||
if(NOT ${TREE_SITTER_ABI_VERSION} MATCHES "^[0-9]+$")
|
|
||||||
unset(TREE_SITTER_ABI_VERSION CACHE)
|
|
||||||
message(FATAL_ERROR "TREE_SITTER_ABI_VERSION must be an integer")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
|
||||||
|
|
||||||
find_program(TREE_SITTER_CLI tree-sitter DOC "Tree-sitter CLI")
|
|
||||||
|
|
||||||
add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/grammar.json"
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/node-types.json"
|
|
||||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/grammar.js"
|
|
||||||
COMMAND "${TREE_SITTER_CLI}" generate grammar.js --no-parser
|
|
||||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
|
||||||
COMMENT "Generating grammar.json")
|
|
||||||
|
|
||||||
add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/parser.c"
|
|
||||||
BYPRODUCTS "${CMAKE_CURRENT_SOURCE_DIR}/src/tree_sitter/parser.h"
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/tree_sitter/alloc.h"
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/tree_sitter/array.h"
|
|
||||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/grammar.json"
|
|
||||||
COMMAND "${TREE_SITTER_CLI}" generate src/grammar.json
|
|
||||||
--abi=${TREE_SITTER_ABI_VERSION}
|
|
||||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
|
||||||
COMMENT "Generating parser.c")
|
|
||||||
|
|
||||||
add_library(tree-sitter-django src/parser.c)
|
|
||||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src/scanner.c)
|
|
||||||
target_sources(tree-sitter-django PRIVATE src/scanner.c)
|
|
||||||
endif()
|
|
||||||
target_include_directories(tree-sitter-django
|
|
||||||
PRIVATE src
|
|
||||||
INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/bindings/c>
|
|
||||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
|
||||||
|
|
||||||
target_compile_definitions(tree-sitter-django PRIVATE
|
|
||||||
$<$<BOOL:${TREE_SITTER_REUSE_ALLOCATOR}>:TREE_SITTER_REUSE_ALLOCATOR>
|
|
||||||
$<$<CONFIG:Debug>:TREE_SITTER_DEBUG>)
|
|
||||||
|
|
||||||
set_target_properties(tree-sitter-django
|
|
||||||
PROPERTIES
|
|
||||||
C_STANDARD 11
|
|
||||||
POSITION_INDEPENDENT_CODE ON
|
|
||||||
SOVERSION "${TREE_SITTER_ABI_VERSION}.${PROJECT_VERSION_MAJOR}"
|
|
||||||
DEFINE_SYMBOL "")
|
|
||||||
|
|
||||||
configure_file(bindings/c/tree-sitter-django.pc.in
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-django.pc" @ONLY)
|
|
||||||
|
|
||||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bindings/c/tree_sitter"
|
|
||||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
|
||||||
FILES_MATCHING PATTERN "*.h")
|
|
||||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-django.pc"
|
|
||||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
|
||||||
install(TARGETS tree-sitter-django
|
|
||||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
|
||||||
|
|
||||||
file(GLOB QUERIES queries/*.scm)
|
|
||||||
install(FILES ${QUERIES}
|
|
||||||
DESTINATION "${CMAKE_INSTALL_DATADIR}/tree-sitter/queries/django")
|
|
||||||
|
|
||||||
add_custom_target(ts-test "${TREE_SITTER_CLI}" test
|
|
||||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
|
||||||
COMMENT "tree-sitter test")
|
|
||||||
-34
@@ -1,34 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "tree-sitter-django"
|
|
||||||
description = "Django grammar for tree-sitter"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Daniel Hanson"]
|
|
||||||
license = "MIT"
|
|
||||||
readme = "README.md"
|
|
||||||
keywords = ["incremental", "parsing", "tree-sitter", "django"]
|
|
||||||
categories = ["parser-implementations", "parsing", "text-editors"]
|
|
||||||
repository = "https://github.com/danhanson/tree-sitter-django"
|
|
||||||
edition = "2021"
|
|
||||||
autoexamples = false
|
|
||||||
|
|
||||||
build = "bindings/rust/build.rs"
|
|
||||||
include = [
|
|
||||||
"bindings/rust/*",
|
|
||||||
"grammar.js",
|
|
||||||
"queries/*",
|
|
||||||
"src/*",
|
|
||||||
"tree-sitter.json",
|
|
||||||
"/LICENSE",
|
|
||||||
]
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
path = "bindings/rust/lib.rs"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
tree-sitter-language = "0.1"
|
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
cc = "1.2"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
tree-sitter = "0.26.12"
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2026 Daniel Hanson
|
|
||||||
|
|
||||||
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.
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
LANGUAGE_NAME := tree-sitter-django
|
|
||||||
HOMEPAGE_URL := https://github.com/danhanson/tree-sitter-django
|
|
||||||
VERSION := 0.1.0
|
|
||||||
DESCRIPTION := Django grammar for tree-sitter
|
|
||||||
|
|
||||||
# repository
|
|
||||||
SRC_DIR := src
|
|
||||||
|
|
||||||
TS ?= tree-sitter
|
|
||||||
|
|
||||||
# install directory layout
|
|
||||||
PREFIX ?= /usr/local
|
|
||||||
DATADIR ?= $(PREFIX)/share
|
|
||||||
INCLUDEDIR ?= $(PREFIX)/include
|
|
||||||
LIBDIR ?= $(PREFIX)/lib
|
|
||||||
BINDIR ?= $(PREFIX)/bin
|
|
||||||
PCLIBDIR ?= $(LIBDIR)/pkgconfig
|
|
||||||
|
|
||||||
# source/object files
|
|
||||||
PARSER := $(SRC_DIR)/parser.c
|
|
||||||
EXTRAS := $(filter-out $(PARSER),$(wildcard $(SRC_DIR)/*.c))
|
|
||||||
OBJS := $(patsubst %.c,%.o,$(PARSER) $(EXTRAS))
|
|
||||||
|
|
||||||
# flags
|
|
||||||
ARFLAGS ?= rcs
|
|
||||||
override CFLAGS += -I$(SRC_DIR) -std=c11 -fPIC
|
|
||||||
|
|
||||||
# ABI versioning
|
|
||||||
SONAME_MAJOR = $(shell sed -n 's/\#define LANGUAGE_VERSION //p' $(PARSER))
|
|
||||||
SONAME_MINOR = $(word 1,$(subst ., ,$(VERSION)))
|
|
||||||
|
|
||||||
# OS-specific bits
|
|
||||||
MACHINE := $(shell $(CC) -dumpmachine)
|
|
||||||
|
|
||||||
ifneq ($(findstring darwin,$(MACHINE)),)
|
|
||||||
SOEXT = dylib
|
|
||||||
SOEXTVER_MAJOR = $(SONAME_MAJOR).$(SOEXT)
|
|
||||||
SOEXTVER = $(SONAME_MAJOR).$(SONAME_MINOR).$(SOEXT)
|
|
||||||
LINKSHARED = -dynamiclib -Wl,-install_name,$(LIBDIR)/lib$(LANGUAGE_NAME).$(SOEXTVER),-rpath,@executable_path/../Frameworks
|
|
||||||
else ifneq ($(findstring mingw32,$(MACHINE)),)
|
|
||||||
SOEXT = dll
|
|
||||||
LINKSHARED += -s -shared -Wl,--out-implib,lib$(LANGUAGE_NAME).dll.a
|
|
||||||
else
|
|
||||||
SOEXT = so
|
|
||||||
SOEXTVER_MAJOR = $(SOEXT).$(SONAME_MAJOR)
|
|
||||||
SOEXTVER = $(SOEXT).$(SONAME_MAJOR).$(SONAME_MINOR)
|
|
||||||
LINKSHARED = -shared -Wl,-soname,lib$(LANGUAGE_NAME).$(SOEXTVER)
|
|
||||||
ifneq ($(filter $(shell uname),FreeBSD NetBSD DragonFly),)
|
|
||||||
PCLIBDIR := $(PREFIX)/libdata/pkgconfig
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) $(LANGUAGE_NAME).pc
|
|
||||||
|
|
||||||
lib$(LANGUAGE_NAME).a: $(OBJS)
|
|
||||||
$(AR) $(ARFLAGS) $@ $^
|
|
||||||
|
|
||||||
lib$(LANGUAGE_NAME).$(SOEXT): $(OBJS)
|
|
||||||
$(CC) $(LDFLAGS) $(LINKSHARED) $^ $(LDLIBS) -o $@
|
|
||||||
ifneq ($(STRIP),)
|
|
||||||
$(STRIP) $@
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(findstring mingw32,$(MACHINE)),)
|
|
||||||
lib$(LANGUAGE_NAME).dll.a: lib$(LANGUAGE_NAME).$(SOEXT)
|
|
||||||
endif
|
|
||||||
|
|
||||||
$(LANGUAGE_NAME).pc: bindings/c/$(LANGUAGE_NAME).pc.in
|
|
||||||
sed -e 's|@PROJECT_VERSION@|$(VERSION)|' \
|
|
||||||
-e 's|@CMAKE_INSTALL_LIBDIR@|$(LIBDIR:$(PREFIX)/%=%)|' \
|
|
||||||
-e 's|@CMAKE_INSTALL_INCLUDEDIR@|$(INCLUDEDIR:$(PREFIX)/%=%)|' \
|
|
||||||
-e 's|@PROJECT_DESCRIPTION@|$(DESCRIPTION)|' \
|
|
||||||
-e 's|@PROJECT_HOMEPAGE_URL@|$(HOMEPAGE_URL)|' \
|
|
||||||
-e 's|@CMAKE_INSTALL_PREFIX@|$(PREFIX)|' $< > $@
|
|
||||||
|
|
||||||
$(SRC_DIR)/grammar.json: grammar.js
|
|
||||||
$(TS) generate --no-parser $^
|
|
||||||
|
|
||||||
$(PARSER): $(SRC_DIR)/grammar.json
|
|
||||||
$(TS) generate $^
|
|
||||||
|
|
||||||
install: all
|
|
||||||
install -d '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/django '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter '$(DESTDIR)$(PCLIBDIR)' '$(DESTDIR)$(LIBDIR)'
|
|
||||||
install -m644 bindings/c/tree_sitter/$(LANGUAGE_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h
|
|
||||||
install -m644 $(LANGUAGE_NAME).pc '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc
|
|
||||||
install -m644 lib$(LANGUAGE_NAME).a '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a
|
|
||||||
install -m755 lib$(LANGUAGE_NAME).$(SOEXT) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER)
|
|
||||||
ifneq ($(findstring mingw32,$(MACHINE)),)
|
|
||||||
install -d '$(DESTDIR)$(BINDIR)'
|
|
||||||
install -m755 lib$(LANGUAGE_NAME).dll '$(DESTDIR)$(BINDIR)'/lib$(LANGUAGE_NAME).dll
|
|
||||||
install -m755 lib$(LANGUAGE_NAME).dll.a '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).dll.a
|
|
||||||
else
|
|
||||||
install -m755 lib$(LANGUAGE_NAME).$(SOEXT) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER)
|
|
||||||
cd '$(DESTDIR)$(LIBDIR)' && ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER) lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR)
|
|
||||||
cd '$(DESTDIR)$(LIBDIR)' && ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) lib$(LANGUAGE_NAME).$(SOEXT)
|
|
||||||
endif
|
|
||||||
ifneq ($(wildcard queries/*.scm),)
|
|
||||||
install -m644 queries/*.scm '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/django
|
|
||||||
endif
|
|
||||||
|
|
||||||
uninstall:
|
|
||||||
$(RM) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a \
|
|
||||||
'$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) \
|
|
||||||
'$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) \
|
|
||||||
'$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) \
|
|
||||||
'$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h \
|
|
||||||
'$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc
|
|
||||||
$(RM) -r '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/django
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(RM) $(OBJS) $(LANGUAGE_NAME).pc lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) lib$(LANGUAGE_NAME).dll.a
|
|
||||||
|
|
||||||
test:
|
|
||||||
$(TS) test
|
|
||||||
|
|
||||||
.PHONY: all install uninstall clean test
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
// swift-tools-version:5.3
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import PackageDescription
|
|
||||||
|
|
||||||
var sources = ["src/parser.c"]
|
|
||||||
if FileManager.default.fileExists(atPath: "src/scanner.c") {
|
|
||||||
sources.append("src/scanner.c")
|
|
||||||
}
|
|
||||||
|
|
||||||
let package = Package(
|
|
||||||
name: "TreeSitterDjango",
|
|
||||||
products: [
|
|
||||||
.library(name: "TreeSitterDjango", targets: ["TreeSitterDjango"]),
|
|
||||||
],
|
|
||||||
dependencies: [
|
|
||||||
.package(url: "https://github.com/tree-sitter/swift-tree-sitter", from: "0.10.0"),
|
|
||||||
],
|
|
||||||
targets: [
|
|
||||||
.target(
|
|
||||||
name: "TreeSitterDjango",
|
|
||||||
dependencies: [],
|
|
||||||
path: ".",
|
|
||||||
sources: sources,
|
|
||||||
resources: [
|
|
||||||
.copy("queries")
|
|
||||||
],
|
|
||||||
publicHeadersPath: "bindings/swift",
|
|
||||||
cSettings: [.headerSearchPath("src")]
|
|
||||||
),
|
|
||||||
.testTarget(
|
|
||||||
name: "TreeSitterDjangoTests",
|
|
||||||
dependencies: [
|
|
||||||
.product(name: "SwiftTreeSitter", package: "swift-tree-sitter"),
|
|
||||||
"TreeSitterDjango",
|
|
||||||
],
|
|
||||||
path: "bindings/swift/TreeSitterDjangoTests"
|
|
||||||
)
|
|
||||||
],
|
|
||||||
cLanguageStandard: .c11
|
|
||||||
)
|
|
||||||
@@ -1,75 +1,6 @@
|
|||||||
# tree-sitter-django
|
# tree-sitter-django
|
||||||
|
|
||||||
A [tree-sitter](https://tree-sitter.github.io/tree-sitter/) grammar for the [Django Template Language (DTL)](https://docs.djangoproject.com/en/6.1/ref/templates/language/#the-django-template-language) — the `{% %}` tags, `{{ }}` variables and `{# #}` comments used in Django templates.
|
A [tree-sitter](https://tree-sitter.github.io/tree-sitter/) grammar for the Django Template Language (DTL) — the `{% %}` tags and `{{ }}` variables used in Django templates.
|
||||||
|
|
||||||
## Coverage
|
|
||||||
|
|
||||||
Every tag and filter Django ships as a builtin is modelled — 28 tags and 57 filters as of Django 6.1 —
|
|
||||||
and so is every tag and filter of the five libraries below. Arguments are part of the grammar rather than
|
|
||||||
something a linter checks later, so a builtin written with the wrong ones is a parse error: `{{ x|length:2 }}`
|
|
||||||
and `{% now %}` do not parse, because `length` takes no argument and `now` requires one.
|
|
||||||
|
|
||||||
The target is Django 6.1, including the builtins Django 6 added (`{% partial %}`, `{% partialdef %}`,
|
|
||||||
`{% querystring %}`, `{% csp_nonce_attr %}`). Rather than being written from the documentation, the grammar
|
|
||||||
is checked against a real Django — `Pipfile.lock` pins the version — by enumerating `Engine.default_builtins`
|
|
||||||
for the tag and filter lists and their arities, and by running candidate snippets through both
|
|
||||||
`django.template.Template()` and this parser to compare what each accepts. Where the two deliberately
|
|
||||||
disagree is listed under [Divergences](#divergences-from-django).
|
|
||||||
|
|
||||||
## Using it
|
|
||||||
|
|
||||||
`tree-sitter-django` is [on npm](https://www.npmjs.com/package/tree-sitter-django), and the other language
|
|
||||||
bindings are in place. What is here today:
|
|
||||||
|
|
||||||
- **`src/parser.c` and `src/scanner.c` are generated and committed**, so any tree-sitter host can compile
|
|
||||||
them directly without running the CLI. The scanner is required: block-name matching
|
|
||||||
(`{% block a %}…{% endblock a %}`), the repeated-argument guards and the missing-tag markers live in it.
|
|
||||||
- **`tree-sitter-django.wasm`** is for a `web-tree-sitter` host or an editor that loads Wasm grammars. It
|
|
||||||
is not checked in: `npm run parser-build` makes it, and a release ships it both in the npm package (the
|
|
||||||
`tree-sitter-django/tree-sitter-django.wasm` export) and as an asset on the GitHub release.
|
|
||||||
- **`queries/`** holds the highlight, locals, tags, injection and error queries an editor loads, plus three files
|
|
||||||
meant for a linter. See [Queries](#queries).
|
|
||||||
- **`tree-sitter.json`** names the grammar `django`, scopes it `source.django`, and points at the query
|
|
||||||
files, which is what a tree-sitter host reads to wire all of the above together.
|
|
||||||
- **`bindings/`** holds a binding per language, generated by `tree-sitter init` from the `bindings` and
|
|
||||||
`metadata` sections of `tree-sitter.json`. See [Bindings](#bindings).
|
|
||||||
|
|
||||||
## Bindings
|
|
||||||
|
|
||||||
| Language | Build from a checkout | Entry point |
|
|
||||||
| -------- | ------------------------------------------------------------- | ------------------------------------------------------ |
|
|
||||||
| Node | `npm install`, which uses a prebuilt binary when there is one | `bindings/node/index.js` (ESM), typed by `index.d.ts` |
|
|
||||||
| Rust | `cargo build` | `bindings/rust/lib.rs`, `Cargo.toml` |
|
|
||||||
| Python | `pip install .` | `bindings/python/tree_sitter_django`, `pyproject.toml` |
|
|
||||||
| Go | `go test ./bindings/go` | `bindings/go/binding.go`, `go.mod` |
|
|
||||||
| Swift | `swift build` | `bindings/swift/TreeSitterDjango`, `Package.swift` |
|
|
||||||
| C / C++ | `make` (static, shared and a pkg-config file) or `cmake` | `bindings/c/tree_sitter/tree-sitter-django.h` |
|
|
||||||
|
|
||||||
```js
|
|
||||||
import Parser from "tree-sitter";
|
|
||||||
import django from "tree-sitter-django";
|
|
||||||
|
|
||||||
const parser = new Parser();
|
|
||||||
parser.setLanguage(django);
|
|
||||||
```
|
|
||||||
|
|
||||||
To use the parser on a website, the wasm needs to be served then loaded.
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { Language, Parser } from "web-tree-sitter";
|
|
||||||
|
|
||||||
await Parser.init();
|
|
||||||
const wasm = "my-resources-path/tree-sitter-django.wasm";
|
|
||||||
const parser = new Parser();
|
|
||||||
parser.setLanguage(await Language.load(wasm));
|
|
||||||
```
|
|
||||||
|
|
||||||
```python
|
|
||||||
import tree_sitter, tree_sitter_django
|
|
||||||
|
|
||||||
language = tree_sitter.Language(tree_sitter_django.language())
|
|
||||||
tree = tree_sitter.Parser(language).parse(b"{% if x %}hi {{ y|upper }}{% endif %}")
|
|
||||||
```
|
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
@@ -81,65 +12,6 @@ npm run parser-build # build the WASM binary
|
|||||||
npm run playground # interactively explore the grammar
|
npm run playground # interactively explore the grammar
|
||||||
```
|
```
|
||||||
|
|
||||||
`src/parser.c`, `src/grammar.json` and `src/node-types.json` are generated **and committed**, so a change
|
|
||||||
to `grammar.js` or `src/scanner.c` is only half made until `parser-generate` has run and the result is
|
|
||||||
committed alongside it. `tree-sitter test` compiles the parser itself, so a stale `src/` shows up as tests
|
|
||||||
that pass against the wrong grammar.
|
|
||||||
|
|
||||||
Pull requests run the corpus tests and every binding through `.github/workflows/ci.yml`. A release is a
|
|
||||||
version-bump commit on `main`: raise the version in `package.json` and in `tree-sitter.json`'s `metadata`,
|
|
||||||
run `npm run parser-generate`, and push. The workflow tags `v<version>`, attaches
|
|
||||||
`tree-sitter-django.wasm` to the GitHub release, and stages the npm publish with provenance and prebuilt
|
|
||||||
binaries for Linux, macOS and Windows. Staging is not publishing: npm holds the tarball until a maintainer
|
|
||||||
runs `npm stage approve <stage-id>` with 2FA, and the workflow's job summary carries that command. Running
|
|
||||||
the workflow by hand stages the current version if npm does not have it yet, which is how a release that
|
|
||||||
failed part way through is retried.
|
|
||||||
|
|
||||||
## Queries
|
|
||||||
|
|
||||||
Five of the files in `queries/` are query files an editor loads:
|
|
||||||
|
|
||||||
- **`highlights.scm`** — syntax highlighting. Tag and filter names are listed one by one, so a name the
|
|
||||||
grammar knows is captured as `@function` and a name it is only tolerating as `@function.call`.
|
|
||||||
- **`locals.scm`** — scopes, definitions and references, so an editor can resolve a variable to the tag
|
|
||||||
that bound it. A definition is a `variable:` field; the scopes are the blocks whose bindings do not
|
|
||||||
outlive them (`{% with %}`, `{% for %}`, `{% empty %}`, `{% block %}`, `{% partialdef %}`,
|
|
||||||
`{% blocktranslate %}`).
|
|
||||||
- **`tags.scm`** — the symbol index behind `tree-sitter tag`. A `{% partialdef %}` and the names a
|
|
||||||
`{% load %}` brings in are definitions; every tag and filter used is a reference.
|
|
||||||
- **`injections.scm`** — marks template text and `{% verbatim %}` bodies as another language's content, so
|
|
||||||
the HTML around the tags can be parsed by its own grammar. It names no language, leaving the editor to
|
|
||||||
supply one.
|
|
||||||
- **`errors.scm`** — what to report as a problem: `(ERROR)` as `@error.syntax`, tree-sitter's own
|
|
||||||
`(MISSING)` as `@error.missing`, and `@error.missing_tag` for the marker placed where a group's required
|
|
||||||
tag is missing. An unterminated `{% if a %}x` parses as an `if_group` ending in a zero-width
|
|
||||||
`missing_endif_tag` rather than as an `ERROR`, so completion and the scope queries keep working while
|
|
||||||
a template is being written — and the tree reports no error of its own, so this query is how to find
|
|
||||||
it. A marker is placed only where the scanner can tell: at the end of input, before an end tag that
|
|
||||||
belongs to an enclosing group, or before an `{% endblock %}` naming a block further out.
|
|
||||||
A group's tag written where no open group can hold it, such as `{% else %}` inside a `{% for %}`, is an
|
|
||||||
`unexpected_tag`, captured as `@error.unexpected_tag`. Words a tag does not take, such as the `x` in
|
|
||||||
`{% else x %}`, are an `unexpected_argument` inside that tag, captured as `@error.unexpected_argument`. A `{{` whose `}}` is missing closes with a zero-width
|
|
||||||
`missing_variable_close`, captured as `@error.missing_variable_close`, so the rest of the template still parses.
|
|
||||||
|
|
||||||
The other three are data for a tool rather than queries an editor runs. Each captures the two halves of a
|
|
||||||
relation a tree-sitter query cannot express, and the tool does the join:
|
|
||||||
|
|
||||||
- **`libraries.scm`** — which library each tag or filter is registered in, and what each `{% load %}`
|
|
||||||
brings in. The grammar never requires the load, so reporting a missing one is a linter's job; a query
|
|
||||||
has no ordering predicate to compare the positions itself.
|
|
||||||
- **`exports.scm`** — a name a tag binds in the scope _around_ it rather than the scope it opens. Only
|
|
||||||
`{% blocktranslate %}`'s `asvar` does that, and a locals query cannot say so: it places a definition in
|
|
||||||
the innermost scope containing it and offers no way out again.
|
|
||||||
- **`conditionals.scm`** — which bodies render on only some passes, as `@conditional.group` /
|
|
||||||
`@conditional.branch` / `@conditional.default`, so a checker can tell that
|
|
||||||
`{% if a %}{% now "Y" as n %}{% endif %}{{ n }}` may reach `{{ n }}` with nothing bound. A group is
|
|
||||||
exhaustive exactly when one of its branches is a default. A locals query has no notion of a path not
|
|
||||||
taken.
|
|
||||||
|
|
||||||
`tree-sitter test` loads every file in the directory, so a pattern naming a node that no longer exists
|
|
||||||
fails the suite rather than quietly matching nothing.
|
|
||||||
|
|
||||||
## Django libraries
|
## Django libraries
|
||||||
|
|
||||||
Five of Django's template libraries are not builtins: their names have to be `{% load %}`ed, or preloaded
|
Five of Django's template libraries are not builtins: their names have to be `{% load %}`ed, or preloaded
|
||||||
@@ -165,9 +37,6 @@ Because these names are modelled, they win over the fallbacks below: a project t
|
|||||||
under one of them with a different signature gets a parse error. They are common enough that shadowing
|
under one of them with a different signature gets a parse error. They are common enough that shadowing
|
||||||
them is treated as the mistake.
|
them is treated as the mistake.
|
||||||
|
|
||||||
If a project insists on shadowing one of these tags, it may use a sub-grammar that replaces the rule with
|
|
||||||
their own. See [Adding rules for your own tags and filters](###adding-rules-for-your-own-tags-and-filters).
|
|
||||||
|
|
||||||
## Custom tags and filters
|
## Custom tags and filters
|
||||||
|
|
||||||
A library's tags and filters are registered in Python, so the grammar cannot know their names, their
|
A library's tags and filters are registered in Python, so the grammar cannot know their names, their
|
||||||
@@ -175,9 +44,10 @@ arity, or whether a tag opens a body. Two fallback rules accept them:
|
|||||||
|
|
||||||
- **Tags.** Any tag the grammar does not recognise parses as `custom_tag`, with the shape `simple_tag` and
|
- **Tags.** Any tag the grammar does not recognise parses as `custom_tag`, with the shape `simple_tag` and
|
||||||
`inclusion_tag` give: positional filter expressions, then `name=value` keyword arguments, then an
|
`inclusion_tag` give: positional filter expressions, then `name=value` keyword arguments, then an
|
||||||
optional `as name`. So `{% mytag a b|upper "s" k=1 as out %}` parses, with the name on the `tag_name:` field.
|
optional `as name`. So `{% mytag a b|upper "s" k=1 as out %}` parses, with the name on the `tag:` field.
|
||||||
A keyword argument written twice is refused.
|
A keyword argument written twice is refused, as `parse_bits` refuses it.
|
||||||
- **Filters.** An unknown filter parses as `(filter filter_name: (identifier))` with at most one `:argument`. No arity check for unknown filters is possible.
|
- **Filters.** An unknown filter parses as `(filter name: (identifier))` with at most one `:argument`,
|
||||||
|
which is all Django's expression regex allows. No arity check is possible.
|
||||||
|
|
||||||
Both are captured as `@function.call` rather than `@function`, so an editor can distinguish a name the
|
Both are captured as `@function.call` rather than `@function`, so an editor can distinguish a name the
|
||||||
grammar knows from one it is only tolerating.
|
grammar knows from one it is only tolerating.
|
||||||
@@ -190,102 +60,69 @@ What the fallbacks cannot do:
|
|||||||
whose arguments are not the `simple_tag` shape — `{% mytag <<>> %}` — is an error here and not in Django.
|
whose arguments are not the `simple_tag` shape — `{% mytag <<>> %}` — is an error here and not in Django.
|
||||||
- **A misspelled name cannot be caught.** `{{ x|lenght }}` is indistinguishable from a filter some library
|
- **A misspelled name cannot be caught.** `{{ x|lenght }}` is indistinguishable from a filter some library
|
||||||
registered. Cross-referencing names against `{% load %}` needs the project's Python, so it belongs in a
|
registered. Cross-referencing names against `{% load %}` needs the project's Python, so it belongs in a
|
||||||
linter; `queries/libraries.scm` and the `load_tag` rule supply what one needs.
|
linter; `queries/libraries.scm` and the `load` rule supply what one needs.
|
||||||
- **Names that only exist inside a tag group are reserved**, so `{% endif %}` or `{% empty %}` standing on
|
- **Names that only exist inside a tag group are reserved**, so `{% endif %}` or `{% empty %}` standing on
|
||||||
its own is an `unexpected_tag`, reported by `errors.scm`, rather than a call to a custom tag of that name.
|
its own is an error rather than a call to a custom tag of that name.
|
||||||
|
|
||||||
### Adding rules for your own tags and filters
|
### Adding rules for your own tags and filters
|
||||||
|
|
||||||
For a project whose custom tags deserve real rules rather than the fallbacks, use this grammar as a base
|
For a project whose custom tags deserve real rules rather than the fallbacks, use this grammar as a base
|
||||||
grammar. `grammar(base, {...})` merges your rules into it, and a rule that redefines one the base already
|
grammar. `grammar(base, {...})` merges your rules into it, and a rule that redefines one the base already
|
||||||
has receives it as `previous`. A tag is an alternative of `template_tag`; a filter is an
|
has receives it as `previous`. A tag is an alternative of `template_block_groups`; a filter is an
|
||||||
alternative of `filter`.
|
alternative of `filter`.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import django from "tree-sitter-django/grammar";
|
import django from "tree-sitter-django/grammar";
|
||||||
|
|
||||||
|
const SEP = /[ \t\r\n]+/;
|
||||||
|
|
||||||
export default grammar(django, {
|
export default grammar(django, {
|
||||||
name: "djangox",
|
name: "djangox",
|
||||||
|
|
||||||
conflicts: ($, previous) => [...previous, [$.loop_block]],
|
|
||||||
|
|
||||||
rules: {
|
rules: {
|
||||||
template_tag: ($, previous) => choice(previous, $.map_tag, $.loop_group),
|
|
||||||
|
|
||||||
// {% map items over rows %}
|
// {% map items over rows %}
|
||||||
|
template_block_groups: ($, previous) => choice(previous, $.map_tag),
|
||||||
map_tag: ($) =>
|
map_tag: ($) =>
|
||||||
seq(
|
seq(
|
||||||
$.simpleTagOpen,
|
"{%",
|
||||||
field("tag_name", "map"),
|
optional(SEP),
|
||||||
$._sep,
|
"map",
|
||||||
|
SEP,
|
||||||
$.filtered_value,
|
$.filtered_value,
|
||||||
$._sep,
|
SEP,
|
||||||
"over",
|
"over",
|
||||||
$._sep,
|
SEP,
|
||||||
$.filtered_value,
|
$.filtered_value,
|
||||||
$.simpleTagClose,
|
optional(SEP),
|
||||||
),
|
"%}",
|
||||||
|
|
||||||
// {% loop x %}…{% endloop %}
|
|
||||||
loop_tag: ($) =>
|
|
||||||
seq(
|
|
||||||
$.startTagOpen,
|
|
||||||
field("tag_name", "loop"),
|
|
||||||
$._sep,
|
|
||||||
$.identifier,
|
|
||||||
$.startTagClose,
|
|
||||||
),
|
|
||||||
loop_block: ($) => seq($.loop_tag, optional($.template)),
|
|
||||||
endloop_tag: ($) =>
|
|
||||||
seq($.endTagOpen, field("tag_name", "endloop"), $.endTagClose),
|
|
||||||
loop_group: ($) =>
|
|
||||||
seq(
|
|
||||||
$.loop_block,
|
|
||||||
choice($.endloop_tag, alias($._missing_tag, $.missing_endloop_tag)),
|
|
||||||
),
|
),
|
||||||
|
|
||||||
// {{ value|shout:"!" }}
|
// {{ value|shout:"!" }}
|
||||||
filter: ($, previous) =>
|
filter: ($, previous) =>
|
||||||
choice(
|
choice(
|
||||||
previous,
|
previous,
|
||||||
seq(field("filter_name", "shout"), ":", field("argument", $.value)),
|
seq(field("name", "shout"), ":", field("argument", $.value)),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
Seven things to know:
|
Four things to know:
|
||||||
|
|
||||||
- **Whitespace is explicit.** `extras` is empty, because Django splits a tag's contents before parsing any
|
- **Whitespace is explicit.** `extras` is empty, because Django splits a tag's contents before parsing any
|
||||||
argument, so every separator has to be written out. The `part`/`tag`/`simpleTag` helpers the base
|
argument, so every separator has to be written out. The `part`/`block`/`simpleTag` helpers the base
|
||||||
grammar is built from are private to it, but the separator is the hidden rule `$._sep`, and it and the
|
grammar is built from are private to it, hence the `SEP` above.
|
||||||
tag utilities (`simpleTagOpen` and the rest) are rules, so an extending grammar uses them as they are.
|
|
||||||
- **Every tag begins with one of the opens**: `$.simpleTagOpen`, with `$.simpleTagClose` at its end, for a
|
|
||||||
tag outside any group such as `map_tag`, and `startTagOpen`, `followTagOpen`, `repeatTagOpen` or
|
|
||||||
`endTagOpen` for the tags of a group. Its
|
|
||||||
zero-width token hands the tag's name to the scanner and is taken wherever a tag can start, so a tag
|
|
||||||
written from a bare `"{%"` never matches: `{% map items over rows %}` would quietly parse as a
|
|
||||||
`custom_tag` instead.
|
|
||||||
- **A new name wins over the fallback.** `shout` becomes a token of its own, so it commits to your
|
- **A new name wins over the fallback.** `shout` becomes a token of its own, so it commits to your
|
||||||
alternative and your arity applies — `{{ x|shout }}` is now an error, while names you have not modelled
|
alternative and your arity applies — `{{ x|shout }}` is now an error, while names you have not modelled
|
||||||
still fall through to `(filter filter_name: (identifier))`.
|
still fall through to `(filter name: (identifier))`.
|
||||||
- **A tag with a body is split the way the base grammar's are**, so every `{% %}` is a node of its own:
|
- **A tag with a body needs a `conflicts` entry**, as every clause in the base grammar does:
|
||||||
a `loop_tag` ending in `$.startTagClose`, a `loop_block` of that tag and the body, an
|
`conflicts: ($, previous) => [...previous, [$.map_clause]]`. The generator offers an associativity
|
||||||
`endloop_tag` built from `$.endTagOpen` and `$.endTagClose`, and a `loop_group` of the block and the
|
instead; taking it silently discards the parse in which the body continues. Its end tag is not reserved
|
||||||
end tag. A middle tag uses `followTagOpen`/`followTagClose` if the group holds it at most once, and
|
either, so a stray `{% endmap %}` parses as a `custom_tag` rather than an error — `reserved` takes no
|
||||||
`repeatTagOpen`/`repeatTagClose` if it may repeat; the scanner trusts that choice. The block needs a
|
`previous`, so the `tag_name` list cannot be added to a name at a time.
|
||||||
`conflicts` entry, as every block in the base grammar does. The generator offers an associativity
|
|
||||||
instead; taking it silently discards the parse in which the body continues.
|
|
||||||
- **End tags are not reserved**, a stray `{% endmap %}` parses as a `custom_tag` rather than an error — `reserved` takes no
|
|
||||||
`previous`, so the `tag_name` list cannot be added to a name at a time. Instead you may drop the `custom_tag` rule to avoid parsing end tags as custom tags. While the fallback
|
|
||||||
is there, stray words in one of your end tags (`{% endloop extra %}`) read as a `custom_tag` too, which
|
|
||||||
leaves your group with a missing-tag marker at the end of input instead of an `unexpected_argument`.
|
|
||||||
- **Your groups get missing-tag markers.** The scanner knows no group by name — a group is closed by `end`
|
|
||||||
followed by its opening tag's name — so the `alias($._missing_tag, $.missing_endloop_tag)` choice
|
|
||||||
above is all it takes: an unclosed `{% loop x %}`, or one left open inside an `{% if %}` that
|
|
||||||
`{% endif %}` closes, holds a `missing_endloop_tag`. Add the name to your copy of `errors.scm`.
|
|
||||||
- **The external scanner has to be re-exported under your grammar's name**, or block-name matching and the
|
- **The external scanner has to be re-exported under your grammar's name**, or block-name matching and the
|
||||||
repeated-argument guards will not link. Give your grammar a `src/scanner.c` that renames the base's five entry points to the
|
repeated-argument guards will not link. `exports` cannot deliver it — that is Node's resolver, and the
|
||||||
|
scanner is C — so give your grammar a `src/scanner.c` that renames the base's five entry points to the
|
||||||
ones your generated `parser.c` calls, and includes it:
|
ones your generated `parser.c` calls, and includes it:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
@@ -304,37 +141,16 @@ path, hence the relative `#include`; the package also exports `tree-sitter-djang
|
|||||||
build step can hand the compiler an absolute path from `import.meta.resolve` where a package manager's
|
build step can hand the compiler an absolute path from `import.meta.resolve` where a package manager's
|
||||||
layout makes the relative one unreliable.
|
layout makes the relative one unreliable.
|
||||||
|
|
||||||
**Turning the fallbacks off.** A grammar that models every tag and filter its project uses probably does
|
|
||||||
not want `custom_tag` and `_custom_filter` accepting unrecognized names as they allow typos to parse. `previous` is the base rule whose `members` are filterable. We can filter out these rules to make the grammar more strict:
|
|
||||||
|
|
||||||
```js
|
|
||||||
template_tag: ($, previous) =>
|
|
||||||
choice(
|
|
||||||
...previous.members.filter((m) => m.name !== "custom_tag"),
|
|
||||||
$.map_tag,
|
|
||||||
),
|
|
||||||
|
|
||||||
filter: ($, previous) =>
|
|
||||||
choice(
|
|
||||||
...previous.members.filter((m) => m.name !== "_custom_filter"),
|
|
||||||
seq(field("name", "shout"), ":", field("argument", $.value)),
|
|
||||||
),
|
|
||||||
```
|
|
||||||
|
|
||||||
`{% mytag %}` and `{{ x|unknown }}` are then errors, while the builtins, the libraries and your own rules
|
|
||||||
carry on as before.
|
|
||||||
|
|
||||||
## Divergences from Django
|
## Divergences from Django
|
||||||
|
|
||||||
The grammar aims to accept what Django accepts, with one deliberate exception: where Django takes an
|
The grammar aims to accept what Django accepts, with one deliberate exception. Where Django takes an
|
||||||
input without complaint but the input is almost certainly a mistake. It reads the mistake and silently
|
input without complaint but the input is almost certainly a mistake — it parses, and then silently
|
||||||
renders nothing or quietly ignores half of what was written. This grammar tries to report such mistakes
|
renders nothing or quietly ignores half of what was written — the grammar reports an error instead.
|
||||||
as errors instead. Every case below is input Django itself accepts:
|
Every case below is input Django itself accepts:
|
||||||
|
|
||||||
- **Number-shaped names.** Django has no number token: a word is a literal if `int()` or `float()` parses
|
- **Number-shaped names.** Django has no number token: a word is a literal if `int()` or `float()` parses
|
||||||
it and a variable lookup otherwise, so `0x1f`, `1a`, `1.`, `1.2.3` and `1__0` look up a variable of that
|
it and a variable lookup otherwise, so `0x1f`, `1a`, `1.`, `1.2.3` and `1__0` look up a variable of that
|
||||||
name and render nothing. (`1.` really is a lookup there and not a float — `Variable` rejects a trailing
|
name and render nothing.
|
||||||
dot after parsing it — while `1.e5` is a float, and both are treated that way here.)
|
|
||||||
- **An attribute of `True`, `False` or `None`.** Every Django context is seeded with those three names, so
|
- **An attribute of `True`, `False` or `None`.** Every Django context is seeded with those three names, so
|
||||||
`{{ True.x }}` is an ordinary two-part lookup that can never resolve.
|
`{{ True.x }}` is an ordinary two-part lookup that can never resolve.
|
||||||
- **A keyword argument written twice.** `{% with a=1 a=2 %}`, and the same in `{% include %}` and
|
- **A keyword argument written twice.** `{% with a=1 a=2 %}`, and the same in `{% include %}` and
|
||||||
@@ -348,7 +164,3 @@ as errors instead. Every case below is input Django itself accepts:
|
|||||||
|
|
||||||
In the other direction the grammar is more permissive only where it cannot know better, which is what the
|
In the other direction the grammar is more permissive only where it cannot know better, which is what the
|
||||||
fallbacks above are for.
|
fallbacks above are for.
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
MIT — see [LICENSE](LICENSE).
|
|
||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
{
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"target_name": "tree_sitter_django_binding",
|
|
||||||
"dependencies": [
|
|
||||||
"<!(node -p \"require('node-addon-api').targets\"):node_addon_api_except",
|
|
||||||
],
|
|
||||||
"include_dirs": [
|
|
||||||
"src",
|
|
||||||
],
|
|
||||||
"sources": [
|
|
||||||
"bindings/node/binding.cc",
|
|
||||||
"src/parser.c",
|
|
||||||
],
|
|
||||||
"variables": {
|
|
||||||
"has_scanner": "<!(node -p \"fs.existsSync('src/scanner.c')\")"
|
|
||||||
},
|
|
||||||
"conditions": [
|
|
||||||
["has_scanner=='true'", {
|
|
||||||
"sources+": ["src/scanner.c"],
|
|
||||||
}],
|
|
||||||
["OS!='win'", {
|
|
||||||
"cflags_c": [
|
|
||||||
"-std=c11",
|
|
||||||
],
|
|
||||||
}, { # OS == "win"
|
|
||||||
"cflags_c": [
|
|
||||||
"/std:c11",
|
|
||||||
"/utf-8",
|
|
||||||
],
|
|
||||||
}],
|
|
||||||
],
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
prefix=@CMAKE_INSTALL_PREFIX@
|
|
||||||
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
|
|
||||||
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
|
|
||||||
|
|
||||||
Name: tree-sitter-django
|
|
||||||
Description: @PROJECT_DESCRIPTION@
|
|
||||||
URL: @PROJECT_HOMEPAGE_URL@
|
|
||||||
Version: @PROJECT_VERSION@
|
|
||||||
Libs: -L${libdir} -ltree-sitter-django
|
|
||||||
Cflags: -I${includedir}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
#ifndef TREE_SITTER_DJANGO_H_
|
|
||||||
#define TREE_SITTER_DJANGO_H_
|
|
||||||
|
|
||||||
typedef struct TSLanguage TSLanguage;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const TSLanguage *tree_sitter_django(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // TREE_SITTER_DJANGO_H_
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package tree_sitter_django
|
|
||||||
|
|
||||||
// #cgo CFLAGS: -std=c11 -fPIC
|
|
||||||
// #include "../../src/parser.c"
|
|
||||||
// #if __has_include("../../src/scanner.c")
|
|
||||||
// #include "../../src/scanner.c"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
// Get the tree-sitter Language for this grammar.
|
|
||||||
func Language() unsafe.Pointer {
|
|
||||||
return unsafe.Pointer(C.tree_sitter_django())
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package tree_sitter_django_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
tree_sitter "github.com/tree-sitter/go-tree-sitter"
|
|
||||||
tree_sitter_django "github.com/danhanson/tree-sitter-django/bindings/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestCanLoadGrammar(t *testing.T) {
|
|
||||||
language := tree_sitter.NewLanguage(tree_sitter_django.Language())
|
|
||||||
if language == nil {
|
|
||||||
t.Errorf("Error loading Django Parser grammar")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
#include <napi.h>
|
|
||||||
|
|
||||||
typedef struct TSLanguage TSLanguage;
|
|
||||||
|
|
||||||
extern "C" TSLanguage *tree_sitter_django();
|
|
||||||
|
|
||||||
// "tree-sitter", "language" hashed with BLAKE2
|
|
||||||
const napi_type_tag LANGUAGE_TYPE_TAG = {
|
|
||||||
0x8AF2E5212AD58ABF, 0xD5006CAD83ABBA16
|
|
||||||
};
|
|
||||||
|
|
||||||
Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
|
||||||
auto language = Napi::External<TSLanguage>::New(env, tree_sitter_django());
|
|
||||||
language.TypeTag(&LANGUAGE_TYPE_TAG);
|
|
||||||
exports["language"] = language;
|
|
||||||
return exports;
|
|
||||||
}
|
|
||||||
|
|
||||||
NODE_API_MODULE(tree_sitter_django_binding, Init)
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import assert from "node:assert";
|
|
||||||
import { test } from "node:test";
|
|
||||||
import Parser from "tree-sitter";
|
|
||||||
|
|
||||||
test("can load grammar", () => {
|
|
||||||
const parser = new Parser();
|
|
||||||
assert.doesNotReject(async () => {
|
|
||||||
const { default: language } = await import("./index.js");
|
|
||||||
parser.setLanguage(language);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Vendored
-60
@@ -1,60 +0,0 @@
|
|||||||
type BaseNode = {
|
|
||||||
type: string;
|
|
||||||
named: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ChildNode = {
|
|
||||||
multiple: boolean;
|
|
||||||
required: boolean;
|
|
||||||
types: BaseNode[];
|
|
||||||
};
|
|
||||||
|
|
||||||
type NodeInfo =
|
|
||||||
| (BaseNode & {
|
|
||||||
subtypes: BaseNode[];
|
|
||||||
})
|
|
||||||
| (BaseNode & {
|
|
||||||
fields: { [name: string]: ChildNode };
|
|
||||||
children: ChildNode[];
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The tree-sitter language object for this grammar.
|
|
||||||
*
|
|
||||||
* @see {@linkcode https://tree-sitter.github.io/node-tree-sitter/interfaces/Parser.Language.html Parser.Language}
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* import Parser from "tree-sitter";
|
|
||||||
* import django from "tree-sitter-django";
|
|
||||||
*
|
|
||||||
* const parser = new Parser();
|
|
||||||
* parser.setLanguage(django);
|
|
||||||
*/
|
|
||||||
declare const binding: {
|
|
||||||
/**
|
|
||||||
* The inner language object.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
language: unknown;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The content of the `node-types.json` file for this grammar.
|
|
||||||
*
|
|
||||||
* @see {@linkplain https://tree-sitter.github.io/tree-sitter/using-parsers/6-static-node-types Static Node Types}
|
|
||||||
*/
|
|
||||||
nodeTypeInfo: NodeInfo[];
|
|
||||||
|
|
||||||
/** The syntax highlighting query for this grammar. */
|
|
||||||
HIGHLIGHTS_QUERY?: string;
|
|
||||||
|
|
||||||
/** The language injection query for this grammar. */
|
|
||||||
INJECTIONS_QUERY?: string;
|
|
||||||
|
|
||||||
/** The local variable query for this grammar. */
|
|
||||||
LOCALS_QUERY?: string;
|
|
||||||
|
|
||||||
/** The symbol tagging query for this grammar. */
|
|
||||||
TAGS_QUERY?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default binding;
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
import { readFileSync } from "node:fs";
|
|
||||||
import { fileURLToPath } from "node:url";
|
|
||||||
|
|
||||||
const root = fileURLToPath(new URL("../..", import.meta.url));
|
|
||||||
|
|
||||||
const binding = typeof process.versions.bun === "string"
|
|
||||||
// Support `bun build --compile` by being statically analyzable enough to find the .node file at build-time
|
|
||||||
? await import(`${root}/prebuilds/${process.platform}-${process.arch}/tree-sitter-django.node`)
|
|
||||||
: (await import("node-gyp-build")).default(root);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const nodeTypes = await import(`${root}/src/node-types.json`, { with: { type: "json" } });
|
|
||||||
binding.nodeTypeInfo = nodeTypes.default;
|
|
||||||
} catch { }
|
|
||||||
|
|
||||||
const queries = [
|
|
||||||
["HIGHLIGHTS_QUERY", `${root}/queries/highlights.scm`],
|
|
||||||
["INJECTIONS_QUERY", `${root}/queries/injections.scm`],
|
|
||||||
["LOCALS_QUERY", `${root}/queries/locals.scm`],
|
|
||||||
["TAGS_QUERY", `${root}/queries/tags.scm`],
|
|
||||||
];
|
|
||||||
|
|
||||||
for (const [prop, path] of queries) {
|
|
||||||
Object.defineProperty(binding, prop, {
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
get() {
|
|
||||||
delete binding[prop];
|
|
||||||
try {
|
|
||||||
binding[prop] = readFileSync(path, "utf8");
|
|
||||||
} catch { }
|
|
||||||
return binding[prop];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export default binding;
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
from unittest import TestCase
|
|
||||||
|
|
||||||
from tree_sitter import Language, Parser
|
|
||||||
import tree_sitter_django
|
|
||||||
|
|
||||||
|
|
||||||
class TestLanguage(TestCase):
|
|
||||||
def test_can_load_grammar(self):
|
|
||||||
try:
|
|
||||||
Parser(Language(tree_sitter_django.language()))
|
|
||||||
except Exception:
|
|
||||||
self.fail("Error loading Django Parser grammar")
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
"""Django grammar for tree-sitter"""
|
|
||||||
|
|
||||||
from importlib.resources import files as _files
|
|
||||||
|
|
||||||
from ._binding import language
|
|
||||||
|
|
||||||
|
|
||||||
def _get_query(name, file):
|
|
||||||
try:
|
|
||||||
query = _files(f"{__package__}") / file
|
|
||||||
globals()[name] = query.read_text()
|
|
||||||
except FileNotFoundError:
|
|
||||||
globals()[name] = None
|
|
||||||
return globals()[name]
|
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name):
|
|
||||||
if name == "HIGHLIGHTS_QUERY":
|
|
||||||
return _get_query("HIGHLIGHTS_QUERY", "queries/highlights.scm")
|
|
||||||
if name == "INJECTIONS_QUERY":
|
|
||||||
return _get_query("INJECTIONS_QUERY", "queries/injections.scm")
|
|
||||||
if name == "LOCALS_QUERY":
|
|
||||||
return _get_query("LOCALS_QUERY", "queries/locals.scm")
|
|
||||||
if name == "TAGS_QUERY":
|
|
||||||
return _get_query("TAGS_QUERY", "queries/tags.scm")
|
|
||||||
|
|
||||||
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
"language",
|
|
||||||
"HIGHLIGHTS_QUERY",
|
|
||||||
"INJECTIONS_QUERY",
|
|
||||||
"LOCALS_QUERY",
|
|
||||||
"TAGS_QUERY",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def __dir__():
|
|
||||||
return sorted(__all__ + [
|
|
||||||
"__all__", "__builtins__", "__cached__", "__doc__", "__file__",
|
|
||||||
"__loader__", "__name__", "__package__", "__path__", "__spec__",
|
|
||||||
])
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
from typing import Final
|
|
||||||
from typing_extensions import CapsuleType
|
|
||||||
|
|
||||||
HIGHLIGHTS_QUERY: Final[str] | None
|
|
||||||
"""The syntax highlighting query for this grammar."""
|
|
||||||
|
|
||||||
INJECTIONS_QUERY: Final[str] | None
|
|
||||||
"""The language injection query for this grammar."""
|
|
||||||
|
|
||||||
LOCALS_QUERY: Final[str] | None
|
|
||||||
"""The local variable query for this grammar."""
|
|
||||||
|
|
||||||
TAGS_QUERY: Final[str] | None
|
|
||||||
"""The symbol tagging query for this grammar."""
|
|
||||||
|
|
||||||
def language() -> CapsuleType:
|
|
||||||
"""The tree-sitter language function for this grammar."""
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
#include <Python.h>
|
|
||||||
|
|
||||||
typedef struct TSLanguage TSLanguage;
|
|
||||||
|
|
||||||
TSLanguage *tree_sitter_django(void);
|
|
||||||
|
|
||||||
static PyObject* _binding_language(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)) {
|
|
||||||
return PyCapsule_New(tree_sitter_django(), "tree_sitter.Language", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct PyModuleDef_Slot slots[] = {
|
|
||||||
#ifdef Py_GIL_DISABLED
|
|
||||||
{Py_mod_gil, Py_MOD_GIL_NOT_USED},
|
|
||||||
#endif
|
|
||||||
{0, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
static PyMethodDef methods[] = {
|
|
||||||
{"language", _binding_language, METH_NOARGS,
|
|
||||||
"Get the tree-sitter language for this grammar."},
|
|
||||||
{NULL, NULL, 0, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct PyModuleDef module = {
|
|
||||||
.m_base = PyModuleDef_HEAD_INIT,
|
|
||||||
.m_name = "_binding",
|
|
||||||
.m_doc = NULL,
|
|
||||||
.m_size = 0,
|
|
||||||
.m_methods = methods,
|
|
||||||
.m_slots = slots,
|
|
||||||
};
|
|
||||||
|
|
||||||
PyMODINIT_FUNC PyInit__binding(void) {
|
|
||||||
return PyModuleDef_Init(&module);
|
|
||||||
}
|
|
||||||
Whitespace-only changes.
@@ -1,56 +0,0 @@
|
|||||||
fn main() {
|
|
||||||
let src_dir = std::path::Path::new("src");
|
|
||||||
|
|
||||||
let mut c_config = cc::Build::new();
|
|
||||||
c_config.std("c11").include(src_dir);
|
|
||||||
|
|
||||||
#[cfg(target_env = "msvc")]
|
|
||||||
c_config.flag("-utf-8");
|
|
||||||
|
|
||||||
if std::env::var("TARGET").unwrap() == "wasm32-unknown-unknown" {
|
|
||||||
let Ok(wasm_headers) = std::env::var("DEP_TREE_SITTER_LANGUAGE_WASM_HEADERS") else {
|
|
||||||
panic!("Environment variable DEP_TREE_SITTER_LANGUAGE_WASM_HEADERS must be set by the language crate");
|
|
||||||
};
|
|
||||||
let Ok(wasm_src) =
|
|
||||||
std::env::var("DEP_TREE_SITTER_LANGUAGE_WASM_SRC").map(std::path::PathBuf::from)
|
|
||||||
else {
|
|
||||||
panic!("Environment variable DEP_TREE_SITTER_LANGUAGE_WASM_SRC must be set by the language crate");
|
|
||||||
};
|
|
||||||
|
|
||||||
c_config.include(&wasm_headers);
|
|
||||||
c_config.files([
|
|
||||||
wasm_src.join("stdio.c"),
|
|
||||||
wasm_src.join("stdlib.c"),
|
|
||||||
wasm_src.join("string.c"),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
let parser_path = src_dir.join("parser.c");
|
|
||||||
c_config.file(&parser_path);
|
|
||||||
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
|
|
||||||
|
|
||||||
let scanner_path = src_dir.join("scanner.c");
|
|
||||||
if scanner_path.exists() {
|
|
||||||
c_config.file(&scanner_path);
|
|
||||||
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
|
|
||||||
}
|
|
||||||
|
|
||||||
c_config.compile("tree-sitter-django");
|
|
||||||
|
|
||||||
println!("cargo:rustc-check-cfg=cfg(with_highlights_query)");
|
|
||||||
if !"queries/highlights.scm".is_empty() && std::path::Path::new("queries/highlights.scm").exists() {
|
|
||||||
println!("cargo:rustc-cfg=with_highlights_query");
|
|
||||||
}
|
|
||||||
println!("cargo:rustc-check-cfg=cfg(with_injections_query)");
|
|
||||||
if !"queries/injections.scm".is_empty() && std::path::Path::new("queries/injections.scm").exists() {
|
|
||||||
println!("cargo:rustc-cfg=with_injections_query");
|
|
||||||
}
|
|
||||||
println!("cargo:rustc-check-cfg=cfg(with_locals_query)");
|
|
||||||
if !"queries/locals.scm".is_empty() && std::path::Path::new("queries/locals.scm").exists() {
|
|
||||||
println!("cargo:rustc-cfg=with_locals_query");
|
|
||||||
}
|
|
||||||
println!("cargo:rustc-check-cfg=cfg(with_tags_query)");
|
|
||||||
if !"queries/tags.scm".is_empty() && std::path::Path::new("queries/tags.scm").exists() {
|
|
||||||
println!("cargo:rustc-cfg=with_tags_query");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
//! This crate provides Django Parser language support for the [tree-sitter] parsing library.
|
|
||||||
//!
|
|
||||||
//! Typically, you will use the [`LANGUAGE`] constant to add this language to a
|
|
||||||
//! tree-sitter [`Parser`], and then use the parser to parse some code:
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! let code = r#"
|
|
||||||
//! "#;
|
|
||||||
//! let mut parser = tree_sitter::Parser::new();
|
|
||||||
//! let language = tree_sitter_django::LANGUAGE;
|
|
||||||
//! parser
|
|
||||||
//! .set_language(&language.into())
|
|
||||||
//! .expect("Error loading Django Parser parser");
|
|
||||||
//! let tree = parser.parse(code, None).unwrap();
|
|
||||||
//! assert!(!tree.root_node().has_error());
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! [`Parser`]: https://docs.rs/tree-sitter/0.26.12/tree_sitter/struct.Parser.html
|
|
||||||
//! [tree-sitter]: https://tree-sitter.github.io/
|
|
||||||
|
|
||||||
use tree_sitter_language::LanguageFn;
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
fn tree_sitter_django() -> *const ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The tree-sitter [`LanguageFn`] for this grammar.
|
|
||||||
pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_django) };
|
|
||||||
|
|
||||||
/// The content of the [`node-types.json`] file for this grammar.
|
|
||||||
///
|
|
||||||
/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers/6-static-node-types
|
|
||||||
pub const NODE_TYPES: &str = include_str!("../../src/node-types.json");
|
|
||||||
|
|
||||||
#[cfg(with_highlights_query)]
|
|
||||||
/// The syntax highlighting query for this grammar.
|
|
||||||
pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm");
|
|
||||||
|
|
||||||
#[cfg(with_injections_query)]
|
|
||||||
/// The language injection query for this grammar.
|
|
||||||
pub const INJECTIONS_QUERY: &str = include_str!("../../queries/injections.scm");
|
|
||||||
|
|
||||||
#[cfg(with_locals_query)]
|
|
||||||
/// The local variable query for this grammar.
|
|
||||||
pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm");
|
|
||||||
|
|
||||||
#[cfg(with_tags_query)]
|
|
||||||
/// The symbol tagging query for this grammar.
|
|
||||||
pub const TAGS_QUERY: &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.into())
|
|
||||||
.expect("Error loading Django Parser parser");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
#ifndef TREE_SITTER_DJANGO_H_
|
|
||||||
#define TREE_SITTER_DJANGO_H_
|
|
||||||
|
|
||||||
typedef struct TSLanguage TSLanguage;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const TSLanguage *tree_sitter_django(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // TREE_SITTER_DJANGO_H_
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import XCTest
|
|
||||||
import SwiftTreeSitter
|
|
||||||
import TreeSitterDjango
|
|
||||||
|
|
||||||
final class TreeSitterDjangoTests: XCTestCase {
|
|
||||||
func testCanLoadGrammar() throws {
|
|
||||||
let parser = Parser()
|
|
||||||
let language = Language(language: tree_sitter_django())
|
|
||||||
XCTAssertNoThrow(try parser.setLanguage(language),
|
|
||||||
"Error loading Django Parser grammar")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
module github.com/danhanson/tree-sitter-django
|
|
||||||
|
|
||||||
go 1.22
|
|
||||||
|
|
||||||
require github.com/tree-sitter/go-tree-sitter v0.24.0
|
|
||||||
|
|
||||||
require github.com/mattn/go-pointer v0.0.1 // indirect
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0=
|
|
||||||
github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
|
||||||
github.com/tree-sitter/go-tree-sitter v0.24.0 h1:kRZb6aBNfcI/u0Qh8XEt3zjNVnmxTisDBN+kXK0xRYQ=
|
|
||||||
github.com/tree-sitter/go-tree-sitter v0.24.0/go.mod h1:x681iFVoLMEwOSIHA1chaLkXlroXEN7WY+VHGFaoDbk=
|
|
||||||
github.com/tree-sitter/tree-sitter-c v0.21.5-0.20240818205408-927da1f210eb h1:A8425heRM8mylnv4H58FPUiH+aYivyitre0PzxrfmWs=
|
|
||||||
github.com/tree-sitter/tree-sitter-c v0.21.5-0.20240818205408-927da1f210eb/go.mod h1:dOF6gtQiF9UwNh995T5OphYmtIypkjsp3ap7r9AN/iA=
|
|
||||||
github.com/tree-sitter/tree-sitter-cpp v0.22.4-0.20240818224355-b1a4e2b25148 h1:AfFPZwtwGN01BW1jDdqBVqscTwetvMpydqYZz57RSlc=
|
|
||||||
github.com/tree-sitter/tree-sitter-cpp v0.22.4-0.20240818224355-b1a4e2b25148/go.mod h1:Bh6U3viD57rFXRYIQ+kmiYtr+1Bx0AceypDLJJSyi9s=
|
|
||||||
github.com/tree-sitter/tree-sitter-embedded-template v0.21.1-0.20240819044651-ffbf64942c33 h1:TwqSV3qLp3tKSqirGLRHnjFk9Tc2oy57LIl+FQ4GjI4=
|
|
||||||
github.com/tree-sitter/tree-sitter-embedded-template v0.21.1-0.20240819044651-ffbf64942c33/go.mod h1:CvCKCt3v04Ufos1zZnNCelBDeCGRpPucaN8QczoUsN4=
|
|
||||||
github.com/tree-sitter/tree-sitter-go v0.21.3-0.20240818010209-8c0f0e7a6012 h1:Xvxck3tE5FW7F7bTS97iNM2ADMyCMJztVqn5HYKdJGo=
|
|
||||||
github.com/tree-sitter/tree-sitter-go v0.21.3-0.20240818010209-8c0f0e7a6012/go.mod h1:T40D0O1cPvUU/+AmiXVXy1cncYQT6wem4Z0g4SfAYvY=
|
|
||||||
github.com/tree-sitter/tree-sitter-html v0.20.5-0.20240818004741-d11201a263d0 h1:c46K6uh5Dz00zJeU9BfjXdb8I+E4RkUdfnWJpQADXFo=
|
|
||||||
github.com/tree-sitter/tree-sitter-html v0.20.5-0.20240818004741-d11201a263d0/go.mod h1:hcNt/kOJHcIcuMvouE7LJcYdeFUFbVpBJ6d4wmOA+tU=
|
|
||||||
github.com/tree-sitter/tree-sitter-java v0.21.1-0.20240824015150-576d8097e495 h1:jrt4qbJVEFs4H93/ITxygHc6u0TGqAkkate7TQ4wFSA=
|
|
||||||
github.com/tree-sitter/tree-sitter-java v0.21.1-0.20240824015150-576d8097e495/go.mod h1:oyaR7fLnRV0hT9z6qwE9GkaeTom/hTDwK3H2idcOJFc=
|
|
||||||
github.com/tree-sitter/tree-sitter-javascript v0.21.5-0.20240818005344-15887341e5b5 h1:om4X9AVg3asL8gxNJDcz4e/Wp+VpQj1PY3uJXKr6EOg=
|
|
||||||
github.com/tree-sitter/tree-sitter-javascript v0.21.5-0.20240818005344-15887341e5b5/go.mod h1:nNqgPoV/h9uYWk6kYEFdEAhNVOacpfpRW5SFmdaP4tU=
|
|
||||||
github.com/tree-sitter/tree-sitter-json v0.21.1-0.20240818005659-bdd69eb8c8a5 h1:pfV3G3k7NCKqKk8THBmyuh2zA33lgYHS3GVrzRR8ry4=
|
|
||||||
github.com/tree-sitter/tree-sitter-json v0.21.1-0.20240818005659-bdd69eb8c8a5/go.mod h1:GbMKRjLfk0H+PI7nLi1Sx5lHf5wCpLz9al8tQYSxpEk=
|
|
||||||
github.com/tree-sitter/tree-sitter-php v0.22.9-0.20240819002312-a552625b56c1 h1:ZXZMDwE+IhUtGug4Brv6NjJWUU3rfkZBKpemf6RY8/g=
|
|
||||||
github.com/tree-sitter/tree-sitter-php v0.22.9-0.20240819002312-a552625b56c1/go.mod h1:UKCLuYnJ312Mei+3cyTmGOHzn0YAnaPRECgJmHtzrqs=
|
|
||||||
github.com/tree-sitter/tree-sitter-python v0.21.1-0.20240818005537-55a9b8a4fbfb h1:EXEM82lFM7JjJb6qiKZXkpIDaCcbV2obNn82ghwj9lw=
|
|
||||||
github.com/tree-sitter/tree-sitter-python v0.21.1-0.20240818005537-55a9b8a4fbfb/go.mod h1:lXCF1nGG5Dr4J3BTS0ObN4xJCCICiSu/b+Xe/VqMV7g=
|
|
||||||
github.com/tree-sitter/tree-sitter-ruby v0.21.1-0.20240818211811-7dbc1e2d0e2d h1:fcYCvoXdcP1uRQYXqJHRy6Hec+uKScQdKVtMwK9JeCI=
|
|
||||||
github.com/tree-sitter/tree-sitter-ruby v0.21.1-0.20240818211811-7dbc1e2d0e2d/go.mod h1:T1nShQ4v5AJtozZ8YyAS4uzUtDAJj/iv4YfwXSbUHzg=
|
|
||||||
github.com/tree-sitter/tree-sitter-rust v0.21.3-0.20240818005432-2b43eafe6447 h1:o9alBu1J/WjrcTKEthYtXmdkDc5OVXD+PqlvnEZ0Lzc=
|
|
||||||
github.com/tree-sitter/tree-sitter-rust v0.21.3-0.20240818005432-2b43eafe6447/go.mod h1:1Oh95COkkTn6Ezp0vcMbvfhRP5gLeqqljR0BYnBzWvc=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
+270
-686
File diff suppressed because it is too large.
Load diff
Generated
-340
@@ -7,29 +7,16 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "tree-sitter-django",
|
"name": "tree-sitter-django",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"hasInstallScript": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"node-addon-api": "^8.3.1",
|
|
||||||
"node-gyp-build": "^4.8.4",
|
|
||||||
"web-tree-sitter": "^0.26.12"
|
"web-tree-sitter": "^0.26.12"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^9",
|
"eslint": "^9",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"prebuildify": "^6.0.1",
|
|
||||||
"prettier": "^3.9.6",
|
"prettier": "^3.9.6",
|
||||||
"tree-sitter": "^0.25.1",
|
|
||||||
"tree-sitter-cli": "^0.26.12",
|
"tree-sitter-cli": "^0.26.12",
|
||||||
"typescript": "^5"
|
"typescript": "^5"
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"tree-sitter": "^0.25.0"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"tree-sitter": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint-community/eslint-utils": {
|
"node_modules/@eslint-community/eslint-utils": {
|
||||||
@@ -326,39 +313,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/base64-js": {
|
|
||||||
"version": "1.5.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
|
||||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/feross"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "patreon",
|
|
||||||
"url": "https://www.patreon.com/feross"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "consulting",
|
|
||||||
"url": "https://feross.org/support"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/bl": {
|
|
||||||
"version": "4.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
|
||||||
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"buffer": "^5.5.0",
|
|
||||||
"inherits": "^2.0.4",
|
|
||||||
"readable-stream": "^3.4.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.18",
|
"version": "1.1.18",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
|
||||||
@@ -370,31 +324,6 @@
|
|||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/buffer": {
|
|
||||||
"version": "5.7.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
|
||||||
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/feross"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "patreon",
|
|
||||||
"url": "https://www.patreon.com/feross"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "consulting",
|
|
||||||
"url": "https://feross.org/support"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"base64-js": "^1.3.1",
|
|
||||||
"ieee754": "^1.1.13"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/callsites": {
|
"node_modules/callsites": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
||||||
@@ -422,13 +351,6 @@
|
|||||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/chownr": {
|
|
||||||
"version": "1.1.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
|
|
||||||
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "ISC"
|
|
||||||
},
|
|
||||||
"node_modules/color-convert": {
|
"node_modules/color-convert": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
@@ -496,16 +418,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/end-of-stream": {
|
|
||||||
"version": "1.4.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
|
|
||||||
"integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"once": "^1.4.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/escape-string-regexp": {
|
"node_modules/escape-string-regexp": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||||
@@ -761,13 +673,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/fs-constants": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/glob-parent": {
|
"node_modules/glob-parent": {
|
||||||
"version": "6.0.2",
|
"version": "6.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||||
@@ -804,27 +709,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ieee754": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
|
||||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/feross"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "patreon",
|
|
||||||
"url": "https://www.patreon.com/feross"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "consulting",
|
|
||||||
"url": "https://feross.org/support"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "BSD-3-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/ignore": {
|
"node_modules/ignore": {
|
||||||
"version": "5.3.2",
|
"version": "5.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
||||||
@@ -862,13 +746,6 @@
|
|||||||
"node": ">=0.8.19"
|
"node": ">=0.8.19"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/inherits": {
|
|
||||||
"version": "2.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
|
||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "ISC"
|
|
||||||
},
|
|
||||||
"node_modules/is-extglob": {
|
"node_modules/is-extglob": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
@@ -1003,23 +880,6 @@
|
|||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/minimist": {
|
|
||||||
"version": "1.2.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
|
||||||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mkdirp-classic": {
|
|
||||||
"version": "0.5.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
|
||||||
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
@@ -1034,62 +894,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/node-abi": {
|
|
||||||
"version": "3.96.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.96.0.tgz",
|
|
||||||
"integrity": "sha512-rebQ/lz7i0EkoLzUVSrKRzA69zMkwLp95kKMWoMDkkM00Suxz0D7zEQPwRml5fQum24mj7bPvmlgLAmu2JCiYg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"semver": "^7.3.5"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/node-addon-api": {
|
|
||||||
"version": "8.9.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.9.2.tgz",
|
|
||||||
"integrity": "sha512-VijLXbi3UACN69I0JVXJsX4tjACjNoQDgv2gTF6sx2wWEi8tkSg2eX8p5gSIFi8z2+DL3oHmY6OyKce38SDolg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": "^18 || ^20 || >= 21"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/node-gyp-build": {
|
|
||||||
"version": "4.8.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
|
|
||||||
"integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"bin": {
|
|
||||||
"node-gyp-build": "bin.js",
|
|
||||||
"node-gyp-build-optional": "optional.js",
|
|
||||||
"node-gyp-build-test": "build-test.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/npm-run-path": {
|
|
||||||
"version": "3.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz",
|
|
||||||
"integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"path-key": "^3.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/once": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"wrappy": "1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/optionator": {
|
"node_modules/optionator": {
|
||||||
"version": "0.9.4",
|
"version": "0.9.4",
|
||||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
|
||||||
@@ -1173,24 +977,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/prebuildify": {
|
|
||||||
"version": "6.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/prebuildify/-/prebuildify-6.0.1.tgz",
|
|
||||||
"integrity": "sha512-8Y2oOOateom/s8dNBsGIcnm6AxPmLH4/nanQzL5lQMU+sC0CMhzARZHizwr36pUPLdvBnOkCNQzxg4djuFSgIw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"minimist": "^1.2.5",
|
|
||||||
"mkdirp-classic": "^0.5.3",
|
|
||||||
"node-abi": "^3.3.0",
|
|
||||||
"npm-run-path": "^3.1.0",
|
|
||||||
"pump": "^3.0.0",
|
|
||||||
"tar-fs": "^2.1.0"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"prebuildify": "bin.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/prelude-ls": {
|
"node_modules/prelude-ls": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||||
@@ -1217,17 +1003,6 @@
|
|||||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/pump": {
|
|
||||||
"version": "3.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz",
|
|
||||||
"integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"end-of-stream": "^1.1.0",
|
|
||||||
"once": "^1.3.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/punycode": {
|
"node_modules/punycode": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||||
@@ -1238,21 +1013,6 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/readable-stream": {
|
|
||||||
"version": "3.6.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
|
||||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"inherits": "^2.0.3",
|
|
||||||
"string_decoder": "^1.1.1",
|
|
||||||
"util-deprecate": "^1.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/resolve-from": {
|
"node_modules/resolve-from": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
||||||
@@ -1263,40 +1023,6 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/safe-buffer": {
|
|
||||||
"version": "5.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
|
||||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/feross"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "patreon",
|
|
||||||
"url": "https://www.patreon.com/feross"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "consulting",
|
|
||||||
"url": "https://feross.org/support"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/semver": {
|
|
||||||
"version": "7.8.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
|
|
||||||
"integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
|
||||||
"bin": {
|
|
||||||
"semver": "bin/semver.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/shebang-command": {
|
"node_modules/shebang-command": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
@@ -1320,16 +1046,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/string_decoder": {
|
|
||||||
"version": "1.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
|
||||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"safe-buffer": "~5.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/strip-json-comments": {
|
"node_modules/strip-json-comments": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
||||||
@@ -1356,48 +1072,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tar-fs": {
|
|
||||||
"version": "2.1.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.5.tgz",
|
|
||||||
"integrity": "sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"chownr": "^1.1.1",
|
|
||||||
"mkdirp-classic": "^0.5.2",
|
|
||||||
"pump": "^3.0.0",
|
|
||||||
"tar-stream": "^2.1.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/tar-stream": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
|
|
||||||
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"bl": "^4.0.3",
|
|
||||||
"end-of-stream": "^1.4.1",
|
|
||||||
"fs-constants": "^1.0.0",
|
|
||||||
"inherits": "^2.0.3",
|
|
||||||
"readable-stream": "^3.1.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/tree-sitter": {
|
|
||||||
"version": "0.25.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.25.1.tgz",
|
|
||||||
"integrity": "sha512-mrcEdkYtHfrK1A6fs3O6FxkBo0Qig5XUXqHhxUOQu0bmPo00QF4XaSx4edpazdHwxnSCjlGKGgIqWdaN4dvTLA==",
|
|
||||||
"dev": true,
|
|
||||||
"hasInstallScript": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"node-addon-api": "^8.5.0",
|
|
||||||
"node-gyp-build": "^4.8.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/tree-sitter-cli": {
|
"node_modules/tree-sitter-cli": {
|
||||||
"version": "0.26.12",
|
"version": "0.26.12",
|
||||||
"resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.26.12.tgz",
|
"resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.26.12.tgz",
|
||||||
@@ -1449,13 +1123,6 @@
|
|||||||
"punycode": "^2.1.0"
|
"punycode": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/util-deprecate": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/web-tree-sitter": {
|
"node_modules/web-tree-sitter": {
|
||||||
"version": "0.26.12",
|
"version": "0.26.12",
|
||||||
"resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.26.12.tgz",
|
"resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.26.12.tgz",
|
||||||
@@ -1488,13 +1155,6 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/wrappy": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "ISC"
|
|
||||||
},
|
|
||||||
"node_modules/yocto-queue": {
|
"node_modules/yocto-queue": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||||
|
|||||||
+3
-46
@@ -1,15 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "tree-sitter-django",
|
"name": "tree-sitter-django",
|
||||||
"version": "0.1.2",
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
|
||||||
"types": "./bindings/node/index.d.ts",
|
|
||||||
"default": "./bindings/node/index.js"
|
|
||||||
},
|
|
||||||
"./grammar": "./grammar.js",
|
"./grammar": "./grammar.js",
|
||||||
"./tree-sitter-django.wasm": "./tree-sitter-django.wasm",
|
|
||||||
"./src/scanner.c": "./src/scanner.c",
|
"./src/scanner.c": "./src/scanner.c",
|
||||||
"./queries/*": "./queries/*",
|
"./queries/*": "./queries/*",
|
||||||
"./package.json": "./package.json"
|
"./package.json": "./package.json"
|
||||||
@@ -24,55 +20,16 @@
|
|||||||
"parser-build": "tree-sitter build --wasm",
|
"parser-build": "tree-sitter build --wasm",
|
||||||
"highlight": "tree-sitter highlight",
|
"highlight": "tree-sitter highlight",
|
||||||
"tag": "tree-sitter tag",
|
"tag": "tree-sitter tag",
|
||||||
"playground": "tree-sitter playground",
|
"playground": "tree-sitter playground"
|
||||||
"install": "node-gyp-build",
|
|
||||||
"prebuildify": "prebuildify --napi --strip --tag-libc",
|
|
||||||
"binding-test": "node --test bindings/node/*_test.js"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"node-addon-api": "^8.3.1",
|
|
||||||
"node-gyp-build": "^4.8.4",
|
|
||||||
"web-tree-sitter": "^0.26.12"
|
"web-tree-sitter": "^0.26.12"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^9",
|
"eslint": "^9",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"prebuildify": "^6.0.1",
|
|
||||||
"prettier": "^3.9.6",
|
"prettier": "^3.9.6",
|
||||||
"tree-sitter": "^0.25.1",
|
|
||||||
"tree-sitter-cli": "^0.26.12",
|
"tree-sitter-cli": "^0.26.12",
|
||||||
"typescript": "^5"
|
"typescript": "^5"
|
||||||
},
|
|
||||||
"description": "Django grammar for tree-sitter",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/danhanson/tree-sitter-django.git"
|
|
||||||
},
|
|
||||||
"author": "Daniel Hanson (https://github.com/danhanson)",
|
|
||||||
"keywords": [
|
|
||||||
"incremental",
|
|
||||||
"parsing",
|
|
||||||
"tree-sitter",
|
|
||||||
"django"
|
|
||||||
],
|
|
||||||
"main": "bindings/node",
|
|
||||||
"types": "bindings/node",
|
|
||||||
"files": [
|
|
||||||
"grammar.js",
|
|
||||||
"tree-sitter.json",
|
|
||||||
"binding.gyp",
|
|
||||||
"prebuilds/**",
|
|
||||||
"bindings/node/*",
|
|
||||||
"queries/*",
|
|
||||||
"src/**",
|
|
||||||
"*.wasm"
|
|
||||||
],
|
|
||||||
"peerDependencies": {
|
|
||||||
"tree-sitter": "^0.25.0"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"tree-sitter": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
[build-system]
|
|
||||||
requires = ["setuptools>=62.4.0", "wheel"]
|
|
||||||
build-backend = "setuptools.build_meta"
|
|
||||||
|
|
||||||
[project]
|
|
||||||
name = "tree-sitter-django"
|
|
||||||
description = "Django grammar for tree-sitter"
|
|
||||||
version = "0.1.0"
|
|
||||||
keywords = ["incremental", "parsing", "tree-sitter", "django"]
|
|
||||||
classifiers = [
|
|
||||||
"Intended Audience :: Developers",
|
|
||||||
"Topic :: Software Development :: Compilers",
|
|
||||||
"Topic :: Text Processing :: Linguistic",
|
|
||||||
"Typing :: Typed",
|
|
||||||
]
|
|
||||||
authors = [{ name = "Daniel Hanson" }]
|
|
||||||
requires-python = ">=3.10"
|
|
||||||
license.text = "MIT"
|
|
||||||
readme = "README.md"
|
|
||||||
|
|
||||||
[project.urls]
|
|
||||||
Homepage = "https://github.com/danhanson/tree-sitter-django"
|
|
||||||
|
|
||||||
[project.optional-dependencies]
|
|
||||||
core = ["tree-sitter~=0.24"]
|
|
||||||
|
|
||||||
[tool.cibuildwheel]
|
|
||||||
build = "cp310-*"
|
|
||||||
build-frontend = "build"
|
|
||||||
+10
-10
@@ -22,7 +22,7 @@
|
|||||||
; If it is not, some pass through it binds nothing, so every definition inside
|
; If it is not, some pass through it binds nothing, so every definition inside
|
||||||
; is conditional. If it is, a definition escapes only when every branch makes
|
; is conditional. If it is, a definition escapes only when every branch makes
|
||||||
; it. Each capture names both halves of the pair, so no ancestor walk is needed
|
; it. Each capture names both halves of the pair, so no ancestor walk is needed
|
||||||
; and no block has to be attributed to a group by name.
|
; and no clause has to be attributed to a group by name.
|
||||||
;
|
;
|
||||||
; Branches nest, so the same test applies again to a group inside a branch.
|
; Branches nest, so the same test applies again to a group inside a branch.
|
||||||
;
|
;
|
||||||
@@ -34,20 +34,20 @@
|
|||||||
; of the three pushes a context, so this is the case the check exists for.
|
; of the three pushes a context, so this is the case the check exists for.
|
||||||
(if_group
|
(if_group
|
||||||
[
|
[
|
||||||
(if_block)
|
(if_clause)
|
||||||
(elif_block)
|
(elif_clause)
|
||||||
] @conditional.branch) @conditional.group
|
] @conditional.branch) @conditional.group
|
||||||
|
|
||||||
(if_group
|
(if_group
|
||||||
(else_block) @conditional.default) @conditional.group
|
(else_clause) @conditional.default) @conditional.group
|
||||||
|
|
||||||
; ifchanged renders its body only when the watched value differs from the
|
; ifchanged renders its body only when the watched value differs from the
|
||||||
; previous pass, and its else otherwise. It pushes no context either.
|
; previous pass, and its else otherwise. It pushes no context either.
|
||||||
(ifchanged_group
|
(ifchanged_group
|
||||||
(ifchanged_block) @conditional.branch) @conditional.group
|
(ifchanged_clause) @conditional.branch) @conditional.group
|
||||||
|
|
||||||
(ifchanged_group
|
(ifchanged_group
|
||||||
(else_block) @conditional.default) @conditional.group
|
(else_clause) @conditional.default) @conditional.group
|
||||||
|
|
||||||
; The loop body runs once per item and empty runs when there are none, so the
|
; The loop body runs once per item and empty runs when there are none, so the
|
||||||
; two partition every render. Both are inside ForNode's context.push() — the
|
; two partition every render. Both are inside ForNode's context.push() — the
|
||||||
@@ -55,21 +55,21 @@
|
|||||||
; nothing escapes either way. Named here because the construct does branch, and
|
; nothing escapes either way. Named here because the construct does branch, and
|
||||||
; because a tool reading only this file should not have to infer that it does.
|
; because a tool reading only this file should not have to infer that it does.
|
||||||
(for_group
|
(for_group
|
||||||
(for_block) @conditional.branch) @conditional.group
|
(for_clause) @conditional.branch) @conditional.group
|
||||||
|
|
||||||
(for_group
|
(for_group
|
||||||
(empty_block) @conditional.default) @conditional.group
|
(empty_clause) @conditional.default) @conditional.group
|
||||||
|
|
||||||
; A cache body is skipped entirely on a cache hit, and CacheNode pushes no
|
; A cache body is skipped entirely on a cache hit, and CacheNode pushes no
|
||||||
; context, so a binding made inside it reaches the rest of the template on the
|
; context, so a binding made inside it reaches the rest of the template on the
|
||||||
; first render and is gone on the next. One branch and no default: never
|
; first render and is gone on the next. One branch and no default: never
|
||||||
; exhaustive, which is the right answer.
|
; exhaustive, which is the right answer.
|
||||||
(cache_group
|
(cache_group
|
||||||
(cache_block) @conditional.branch) @conditional.group
|
(cache_clause) @conditional.branch) @conditional.group
|
||||||
|
|
||||||
; Not here, deliberately: block and partialdef bodies may also fail to render —
|
; Not here, deliberately: block and partialdef bodies may also fail to render —
|
||||||
; a child template overrides the block, and a partial renders only where
|
; a child template overrides the block, and a partial renders only where
|
||||||
; {% partial %} names it — but both blocks are @local.scope in locals.scm, so
|
; {% partial %} names it — but both clauses are @local.scope in locals.scm, so
|
||||||
; nothing they bind escapes to be checked. Bodies that always render once
|
; nothing they bind escapes to be checked. Bodies that always render once
|
||||||
; (with, filter, autoescape, spaceless, language, localize, localtime,
|
; (with, filter, autoescape, spaceless, language, localize, localtime,
|
||||||
; timezone) are not conditional at all, and comment, verbatim and
|
; timezone) are not conditional at all, and comment, verbatim and
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
; Everything in a template that an editor should report as a problem.
|
|
||||||
;
|
|
||||||
; A group whose required tag is missing parses without an ERROR: the scanner
|
|
||||||
; supplies a zero-width marker where the tag belongs, so the group, its blocks
|
|
||||||
; and the scopes they open stay intact for completion and the other queries.
|
|
||||||
; Such a tree has no error of its own (ts_node_has_error is false), so a tool
|
|
||||||
; has to run this query to find them.
|
|
||||||
;
|
|
||||||
; @error.syntax input the grammar could not parse
|
|
||||||
; @error.missing a token that tree-sitter's error recovery inserted
|
|
||||||
; @error.missing_tag expected tag block is missing
|
|
||||||
;
|
|
||||||
; The markers are listed one by one, as MISSING_TAGS in grammar.js: the
|
|
||||||
; generator drops a supertype whose members are aliases, so there is no single
|
|
||||||
; node type to match them all. A new tag group, or a new kind of marker, is
|
|
||||||
; added here.
|
|
||||||
|
|
||||||
(ERROR) @error.syntax
|
|
||||||
|
|
||||||
(MISSING) @error.missing
|
|
||||||
|
|
||||||
[
|
|
||||||
(missing_endautoescape_tag)
|
|
||||||
(missing_endblock_tag)
|
|
||||||
(missing_endblocktrans_tag)
|
|
||||||
(missing_endblocktranslate_tag)
|
|
||||||
(missing_endcache_tag)
|
|
||||||
(missing_endcomment_tag)
|
|
||||||
(missing_endfilter_tag)
|
|
||||||
(missing_endfor_tag)
|
|
||||||
(missing_endif_tag)
|
|
||||||
(missing_endifchanged_tag)
|
|
||||||
(missing_endlanguage_tag)
|
|
||||||
(missing_endlocalize_tag)
|
|
||||||
(missing_endlocaltime_tag)
|
|
||||||
(missing_endpartialdef_tag)
|
|
||||||
(missing_endspaceless_tag)
|
|
||||||
(missing_endtimezone_tag)
|
|
||||||
(missing_endverbatim_tag)
|
|
||||||
(missing_endwith_tag)
|
|
||||||
(missing_plural_tag)] @error.missing_tag
|
|
||||||
|
|
||||||
(unexpected_tag) @error.unexpected_tag
|
|
||||||
|
|
||||||
(unexpected_argument) @error.unexpected_argument
|
|
||||||
|
|
||||||
(missing_variable_close) @error.missing_variable_close
|
|
||||||
+2
-7
@@ -21,10 +21,5 @@
|
|||||||
; scope span could have separated them; that is why this is a separate file
|
; scope span could have separated them; that is why this is a separate file
|
||||||
; rather than a narrower scope in locals.scm.
|
; rather than a narrower scope in locals.scm.
|
||||||
|
|
||||||
(blocktrans_block
|
(blocktranslate_group
|
||||||
(blocktrans_tag
|
asvar: (identifier) @export.name) @export.from
|
||||||
asvar: (identifier) @export.name)) @export.from
|
|
||||||
|
|
||||||
(blocktranslate_block
|
|
||||||
(blocktranslate_tag
|
|
||||||
asvar: (identifier) @export.name)) @export.from
|
|
||||||
@@ -4,13 +4,13 @@
|
|||||||
variable: (identifier) @variable.parameter
|
variable: (identifier) @variable.parameter
|
||||||
|
|
||||||
|
|
||||||
(block_tag
|
(block_clause
|
||||||
(push_block) @type)
|
(push_block) @type)
|
||||||
|
|
||||||
(partialdef_tag
|
(partialdef_clause
|
||||||
(push_partial) @type)
|
(push_partial) @type)
|
||||||
|
|
||||||
(verbatim_tag
|
(verbatim_group
|
||||||
(push_verbatim) @type)
|
(push_verbatim) @type)
|
||||||
|
|
||||||
(comment_content) @comment
|
(comment_content) @comment
|
||||||
@@ -47,7 +47,7 @@ variable: (identifier) @variable.parameter
|
|||||||
(library
|
(library
|
||||||
(identifier) @module)
|
(identifier) @module)
|
||||||
|
|
||||||
tag_name: [
|
tag: [
|
||||||
("autoescape")
|
("autoescape")
|
||||||
("endautoescape")
|
("endautoescape")
|
||||||
("block")
|
("block")
|
||||||
@@ -120,7 +120,7 @@ tag_name: [
|
|||||||
("endwith")] @function
|
("endwith")] @function
|
||||||
|
|
||||||
(filter
|
(filter
|
||||||
filter_name: [
|
name: [
|
||||||
("add")
|
("add")
|
||||||
("addslashes")
|
("addslashes")
|
||||||
("capfirst")
|
("capfirst")
|
||||||
@@ -190,10 +190,10 @@ tag_name: [
|
|||||||
|
|
||||||
; a filter or tag a "load" brought in, whose name the grammar does not know
|
; a filter or tag a "load" brought in, whose name the grammar does not know
|
||||||
(filter
|
(filter
|
||||||
filter_name: (identifier) @function.call)
|
name: (identifier) @function.call)
|
||||||
|
|
||||||
(custom_tag
|
(custom_tag
|
||||||
tag_name: (identifier) @function.call)
|
tag: (identifier) @function.call)
|
||||||
|
|
||||||
(load_tag
|
(load
|
||||||
(identifier) @function)
|
(identifier) @function)
|
||||||
+39
-40
@@ -15,81 +15,80 @@
|
|||||||
; heads, so that the capture is both the name to look up and the range to
|
; heads, so that the capture is both the name to look up and the range to
|
||||||
; report. A paired tag names the opening tag only.
|
; report. A paired tag names the opening tag only.
|
||||||
|
|
||||||
(static_tag
|
(static
|
||||||
tag_name: ("static") @library.static)
|
tag: ("static") @library.static)
|
||||||
|
|
||||||
(get_static_prefix_tag
|
(get_static_prefix
|
||||||
tag_name: ("get_static_prefix") @library.static)
|
tag: ("get_static_prefix") @library.static)
|
||||||
|
|
||||||
(get_media_prefix_tag
|
(get_media_prefix
|
||||||
tag_name: ("get_media_prefix") @library.static)
|
tag: ("get_media_prefix") @library.static)
|
||||||
|
|
||||||
(blocktrans_tag
|
(blocktranslate_group
|
||||||
tag_name: ("blocktrans") @library.i18n)
|
tag: [
|
||||||
|
("blocktrans")
|
||||||
|
("blocktranslate")] @library.i18n)
|
||||||
|
|
||||||
(blocktranslate_tag
|
(translate
|
||||||
tag_name: ("blocktranslate") @library.i18n)
|
tag: [
|
||||||
|
|
||||||
(translate_tag
|
|
||||||
tag_name: [
|
|
||||||
("trans")
|
("trans")
|
||||||
("translate")] @library.i18n)
|
("translate")] @library.i18n)
|
||||||
|
|
||||||
(language_tag
|
(language_clause
|
||||||
tag_name: ("language") @library.i18n)
|
tag: ("language") @library.i18n)
|
||||||
|
|
||||||
(get_available_languages_tag
|
(get_available_languages
|
||||||
tag_name: ("get_available_languages") @library.i18n)
|
tag: ("get_available_languages") @library.i18n)
|
||||||
|
|
||||||
(get_current_language_tag
|
(get_current_language
|
||||||
tag_name: ("get_current_language") @library.i18n)
|
tag: ("get_current_language") @library.i18n)
|
||||||
|
|
||||||
(get_current_language_bidi_tag
|
(get_current_language_bidi
|
||||||
tag_name: ("get_current_language_bidi") @library.i18n)
|
tag: ("get_current_language_bidi") @library.i18n)
|
||||||
|
|
||||||
(get_language_info_tag
|
(get_language_info
|
||||||
tag_name: ("get_language_info") @library.i18n)
|
tag: ("get_language_info") @library.i18n)
|
||||||
|
|
||||||
(get_language_info_list_tag
|
(get_language_info_list
|
||||||
tag_name: ("get_language_info_list") @library.i18n)
|
tag: ("get_language_info_list") @library.i18n)
|
||||||
|
|
||||||
(filter
|
(filter
|
||||||
filter_name: [
|
name: [
|
||||||
("language_bidi")
|
("language_bidi")
|
||||||
("language_name")
|
("language_name")
|
||||||
("language_name_local")
|
("language_name_local")
|
||||||
("language_name_translated")] @library.i18n)
|
("language_name_translated")] @library.i18n)
|
||||||
|
|
||||||
(cache_tag
|
(cache_clause
|
||||||
tag_name: ("cache") @library.cache)
|
tag: ("cache") @library.cache)
|
||||||
|
|
||||||
(localize_tag
|
(localize_clause
|
||||||
tag_name: ("localize") @library.l10n)
|
tag: ("localize") @library.l10n)
|
||||||
|
|
||||||
(filter
|
(filter
|
||||||
filter_name: [
|
name: [
|
||||||
("localize")
|
("localize")
|
||||||
("unlocalize")] @library.l10n)
|
("unlocalize")] @library.l10n)
|
||||||
|
|
||||||
(localtime_tag
|
(localtime_clause
|
||||||
tag_name: ("localtime") @library.tz)
|
tag: ("localtime") @library.tz)
|
||||||
|
|
||||||
(timezone_tag
|
(timezone_clause
|
||||||
tag_name: ("timezone") @library.tz)
|
tag: ("timezone") @library.tz)
|
||||||
|
|
||||||
(get_current_timezone_tag
|
(get_current_timezone
|
||||||
tag_name: ("get_current_timezone") @library.tz)
|
tag: ("get_current_timezone") @library.tz)
|
||||||
|
|
||||||
(filter
|
(filter
|
||||||
filter_name: [
|
name: [
|
||||||
("localtime")
|
("localtime")
|
||||||
("timezone")
|
("timezone")
|
||||||
("utc")] @library.tz)
|
("utc")] @library.tz)
|
||||||
|
|
||||||
; "{% load static %}" makes every name in the library available; "{% load
|
; "{% load static %}" makes every name in the library available; "{% load
|
||||||
; static from staticfiles %}" makes only the names listed available.
|
; static from staticfiles %}" makes only the names listed available.
|
||||||
(load_tag
|
(load
|
||||||
(library) @load.library)
|
(library) @load.library)
|
||||||
|
|
||||||
(load_tag
|
(load
|
||||||
(identifier) @load.name)
|
(identifier) @load.name)
|
||||||
+8
-9
@@ -6,22 +6,21 @@ variable: (identifier) @local.definition
|
|||||||
; The tags whose Node pushes a context, so that what they bind is not visible
|
; The tags whose Node pushes a context, so that what they bind is not visible
|
||||||
; after them. Verified by rendering: "{% block b %}{% now "Y" as n %}{% endblock %}{{ n }}"
|
; after them. Verified by rendering: "{% block b %}{% now "Y" as n %}{% endblock %}{{ n }}"
|
||||||
; is empty, while the same around an "{% if %}" is not, because if does not push.
|
; is empty, while the same around an "{% if %}" is not, because if does not push.
|
||||||
(with_block) @local.scope
|
(with_clause) @local.scope
|
||||||
(for_block) @local.scope
|
(for_clause) @local.scope
|
||||||
(block_block) @local.scope
|
(block_clause) @local.scope
|
||||||
(partialdef_block) @local.scope
|
(partialdef_clause) @local.scope
|
||||||
|
|
||||||
; ForNode renders nodelist_empty inside the same context.push() as the loop
|
; ForNode renders nodelist_empty inside the same context.push() as the loop
|
||||||
; body, so "{% empty %}" is part of the loop's scope even though it is a
|
; body, so "{% empty %}" is part of the loop's scope even though it is a
|
||||||
; separate block: "{% for x in ys %}a{% empty %}{% now "Y" as n %}{% endfor %}{{ n }}"
|
; separate clause: "{% for x in ys %}a{% empty %}{% now "Y" as n %}{% endfor %}{{ n }}"
|
||||||
; is empty. queries/conditionals.scm names both blocks as branches of the
|
; is empty. queries/conditionals.scm names both clauses as branches of the
|
||||||
; same group and relies on this.
|
; same group and relies on this.
|
||||||
(empty_block) @local.scope
|
(empty_clause) @local.scope
|
||||||
|
|
||||||
; blocktranslate pushes a context for its "with" and "count" bindings. Its
|
; blocktranslate pushes a context for its "with" and "count" bindings. Its
|
||||||
; asvar target is not one of them: it is written in the same tag but assigned
|
; asvar target is not one of them: it is written in the same tag but assigned
|
||||||
; outside it, and carries an "asvar" field rather than "variable" so that this
|
; outside it, and carries an "asvar" field rather than "variable" so that this
|
||||||
; scope does not swallow it. A tool that wants it must define it in the scope
|
; scope does not swallow it. A tool that wants it must define it in the scope
|
||||||
; around the block, which a locals query has no way to say.
|
; around the block, which a locals query has no way to say.
|
||||||
(blocktrans_block) @local.scope
|
(blocktranslate_group) @local.scope
|
||||||
(blocktranslate_block) @local.scope
|
|
||||||
+11
-14
@@ -1,20 +1,17 @@
|
|||||||
(load_tag
|
(load
|
||||||
(identifier) @name) @definition.function
|
(identifier) @name) @definition.function
|
||||||
|
|
||||||
(partialdef_tag (push_partial) @name) @definition.method
|
(partialdef_clause (push_partial) @name) @definition.method
|
||||||
(partial_tag (identifier) @name) @reference.call
|
(partial (identifier) @name) @reference.call
|
||||||
|
|
||||||
; a tag that opens no body names itself; a group is named by the first tag of
|
; every tag that opens a group names itself in a clause of its own, and every
|
||||||
; its first block, so neither its end tag nor the tags opening its later blocks
|
; tag that does not is a group member directly
|
||||||
; are references of their own
|
(template_block_groups
|
||||||
(template_tag
|
[
|
||||||
tag_name: _ @name) @reference.call
|
|
||||||
|
|
||||||
(template_tag
|
|
||||||
.
|
|
||||||
(_
|
|
||||||
.
|
|
||||||
(_
|
(_
|
||||||
tag_name: _ @name))) @reference.call
|
tag: _ @name)
|
||||||
|
(_
|
||||||
|
(_
|
||||||
|
tag: _ @name))] @reference.call)
|
||||||
|
|
||||||
(filter) @reference.call
|
(filter) @reference.call
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
from os import path
|
|
||||||
from sysconfig import get_config_var
|
|
||||||
|
|
||||||
from setuptools import Extension, find_packages, setup
|
|
||||||
from setuptools.command.build import build
|
|
||||||
from setuptools.command.build_ext import build_ext
|
|
||||||
from setuptools.command.egg_info import egg_info
|
|
||||||
from wheel.bdist_wheel import bdist_wheel
|
|
||||||
|
|
||||||
|
|
||||||
class Build(build):
|
|
||||||
def run(self):
|
|
||||||
if path.isdir("queries"):
|
|
||||||
dest = path.join(self.build_lib, "tree_sitter_django", "queries")
|
|
||||||
self.copy_tree("queries", dest)
|
|
||||||
super().run()
|
|
||||||
|
|
||||||
|
|
||||||
class BuildExt(build_ext):
|
|
||||||
def build_extension(self, ext: Extension):
|
|
||||||
if self.compiler.compiler_type != "msvc":
|
|
||||||
ext.extra_compile_args = ["-std=c11", "-fvisibility=hidden"]
|
|
||||||
else:
|
|
||||||
ext.extra_compile_args = ["/std:c11", "/utf-8"]
|
|
||||||
if path.exists("src/scanner.c"):
|
|
||||||
ext.sources.append("src/scanner.c")
|
|
||||||
if ext.py_limited_api:
|
|
||||||
ext.define_macros.append(("Py_LIMITED_API", "0x030A0000"))
|
|
||||||
super().build_extension(ext)
|
|
||||||
|
|
||||||
|
|
||||||
class BdistWheel(bdist_wheel):
|
|
||||||
def get_tag(self):
|
|
||||||
python, abi, platform = super().get_tag()
|
|
||||||
if python.startswith("cp") and not get_config_var("Py_GIL_DISABLED"):
|
|
||||||
python, abi = "cp310", "abi3"
|
|
||||||
return python, abi, platform
|
|
||||||
|
|
||||||
|
|
||||||
class EggInfo(egg_info):
|
|
||||||
def find_sources(self):
|
|
||||||
super().find_sources()
|
|
||||||
self.filelist.recursive_include("queries", "*.scm")
|
|
||||||
self.filelist.include("src/tree_sitter/*.h")
|
|
||||||
self.filelist.include("src/*.c")
|
|
||||||
|
|
||||||
|
|
||||||
setup(
|
|
||||||
packages=find_packages("bindings/python"),
|
|
||||||
package_dir={"": "bindings/python"},
|
|
||||||
package_data={
|
|
||||||
"tree_sitter_django": ["*.pyi", "py.typed"],
|
|
||||||
"tree_sitter_django.queries": ["*.scm"],
|
|
||||||
},
|
|
||||||
ext_package="tree_sitter_django",
|
|
||||||
ext_modules=[
|
|
||||||
Extension(
|
|
||||||
name="_binding",
|
|
||||||
sources=[
|
|
||||||
"bindings/python/tree_sitter_django/binding.c",
|
|
||||||
"src/parser.c",
|
|
||||||
],
|
|
||||||
define_macros=[
|
|
||||||
("PY_SSIZE_T_CLEAN", None),
|
|
||||||
("TREE_SITTER_HIDE_SYMBOLS", None),
|
|
||||||
],
|
|
||||||
include_dirs=["src"],
|
|
||||||
py_limited_api=not get_config_var("Py_GIL_DISABLED"),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
cmdclass={
|
|
||||||
"build": Build,
|
|
||||||
"build_ext": BuildExt,
|
|
||||||
"bdist_wheel": BdistWheel,
|
|
||||||
"egg_info": EggInfo,
|
|
||||||
},
|
|
||||||
zip_safe=False
|
|
||||||
)
|
|
||||||
+3651
-3157
File diff suppressed because it is too large.
Load diff
+557
-1932
File diff suppressed because it is too large.
Load diff
+53271
-50422
File diff suppressed because it is too large.
Load diff
+324
-680
File diff suppressed because it is too large.
Load diff
@@ -17,9 +17,7 @@ Autoescape
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(autoescape_group
|
(autoescape_group
|
||||||
(autoescape_block
|
(autoescape_clause
|
||||||
(autoescape_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endautoescape_tag))
|
|
||||||
(content))
|
(content))
|
||||||
+24
-40
@@ -17,13 +17,11 @@ Block
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(block_group
|
(block_group
|
||||||
(block_block
|
(block_clause
|
||||||
(block_tag
|
name: (push_block)
|
||||||
name: (push_block))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content)))
|
||||||
(endblock_tag
|
(pop_block))
|
||||||
(pop_block)))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -45,13 +43,11 @@ Block Matching End Tag
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(block_group
|
(block_group
|
||||||
(block_block
|
(block_clause
|
||||||
(block_tag
|
name: (push_block)
|
||||||
name: (push_block))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content)))
|
||||||
(endblock_tag
|
(pop_block))
|
||||||
(pop_block)))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -75,22 +71,18 @@ Nested Blocks
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(block_group
|
(block_group
|
||||||
(block_block
|
(block_clause
|
||||||
(block_tag
|
name: (push_block)
|
||||||
name: (push_block))
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(block_group
|
(block_group
|
||||||
(block_block
|
(block_clause
|
||||||
(block_tag
|
name: (push_block)
|
||||||
name: (push_block))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content)))
|
||||||
(endblock_tag
|
(pop_block))
|
||||||
(pop_block)))
|
|
||||||
(content)))
|
(content)))
|
||||||
(endblock_tag
|
(pop_block))
|
||||||
(pop_block)))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -114,22 +106,18 @@ Nested Blocks End Tag
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(block_group
|
(block_group
|
||||||
(block_block
|
(block_clause
|
||||||
(block_tag
|
name: (push_block)
|
||||||
name: (push_block))
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(block_group
|
(block_group
|
||||||
(block_block
|
(block_clause
|
||||||
(block_tag
|
name: (push_block)
|
||||||
name: (push_block))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content)))
|
||||||
(endblock_tag
|
(pop_block))
|
||||||
(pop_block)))
|
|
||||||
(content)))
|
(content)))
|
||||||
(endblock_tag
|
(pop_block))
|
||||||
(pop_block)))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -153,20 +141,16 @@ Nested Blocks Mixed Tags
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(block_group
|
(block_group
|
||||||
(block_block
|
(block_clause
|
||||||
(block_tag
|
name: (push_block)
|
||||||
name: (push_block))
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(block_group
|
(block_group
|
||||||
(block_block
|
(block_clause
|
||||||
(block_tag
|
name: (push_block)
|
||||||
name: (push_block))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content)))
|
||||||
(endblock_tag
|
(pop_block))
|
||||||
(pop_block)))
|
|
||||||
(content)))
|
(content)))
|
||||||
(endblock_tag
|
(pop_block))
|
||||||
(pop_block)))
|
|
||||||
(content))
|
(content))
|
||||||
+82
-331
@@ -9,10 +9,7 @@ Blocktrans
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(blocktranslate_group
|
(blocktranslate_group
|
||||||
(blocktrans_block
|
(content))
|
||||||
(blocktrans_tag)
|
|
||||||
(content))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -26,10 +23,7 @@ Blocktranslate
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(blocktranslate_group
|
(blocktranslate_group
|
||||||
(blocktranslate_block
|
(content))
|
||||||
(blocktranslate_tag)
|
|
||||||
(content))
|
|
||||||
(endblocktranslate_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -42,10 +36,7 @@ Blocktrans Empty
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(blocktranslate_group
|
(blocktranslate_group)
|
||||||
(blocktrans_block
|
|
||||||
(blocktrans_tag))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -59,15 +50,12 @@ Blocktrans With A Placeholder
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(blocktranslate_group
|
(blocktranslate_group
|
||||||
(blocktrans_block
|
(content)
|
||||||
(blocktrans_tag)
|
(template_variable
|
||||||
(content)
|
(filtered_value
|
||||||
(template_variable
|
(value
|
||||||
(filtered_value
|
(variable_attribute
|
||||||
(value
|
(identifier))))))
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -81,10 +69,7 @@ Blocktrans Trimmed
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(blocktranslate_group
|
(blocktranslate_group
|
||||||
(blocktrans_block
|
(content))
|
||||||
(blocktrans_tag)
|
|
||||||
(content))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -98,15 +83,12 @@ Blocktrans With
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(blocktranslate_group
|
(blocktranslate_group
|
||||||
(blocktrans_block
|
variable: (identifier)
|
||||||
(blocktrans_tag
|
(filtered_value
|
||||||
variable: (identifier)
|
(value
|
||||||
(filtered_value
|
(variable_attribute
|
||||||
(value
|
(identifier))))
|
||||||
(variable_attribute
|
(content))
|
||||||
(identifier)))))
|
|
||||||
(content))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -120,20 +102,17 @@ Blocktrans With Several Bindings
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(blocktranslate_group
|
(blocktranslate_group
|
||||||
(blocktrans_block
|
variable: (identifier)
|
||||||
(blocktrans_tag
|
(filtered_value
|
||||||
variable: (identifier)
|
(value
|
||||||
(filtered_value
|
(variable_attribute
|
||||||
(value
|
(identifier))))
|
||||||
(variable_attribute
|
variable: (identifier)
|
||||||
(identifier))))
|
(filtered_value
|
||||||
variable: (identifier)
|
(value
|
||||||
(filtered_value
|
(variable_attribute
|
||||||
(value
|
(identifier))))
|
||||||
(variable_attribute
|
(content))
|
||||||
(identifier)))))
|
|
||||||
(content))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -147,17 +126,14 @@ Blocktrans With A Filtered Binding
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(blocktranslate_group
|
(blocktranslate_group
|
||||||
(blocktrans_block
|
variable: (identifier)
|
||||||
(blocktrans_tag
|
(filtered_value
|
||||||
variable: (identifier)
|
(value
|
||||||
(filtered_value
|
(variable_attribute
|
||||||
(value
|
(identifier)))
|
||||||
(variable_attribute
|
(filter_expression
|
||||||
(identifier)))
|
(filter)))
|
||||||
(filter_expression
|
(content))
|
||||||
(filter))))
|
|
||||||
(content))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -171,14 +147,11 @@ Blocktrans With Context
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(blocktranslate_group
|
(blocktranslate_group
|
||||||
(blocktrans_block
|
(filtered_value
|
||||||
(blocktrans_tag
|
(value
|
||||||
(filtered_value
|
(literal
|
||||||
(value
|
(string))))
|
||||||
(literal
|
(content))
|
||||||
(string)))))
|
|
||||||
(content))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -192,11 +165,8 @@ Blocktrans With Asvar
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(blocktranslate_group
|
(blocktranslate_group
|
||||||
(blocktrans_block
|
asvar: (identifier)
|
||||||
(blocktrans_tag
|
(content))
|
||||||
asvar: (identifier))
|
|
||||||
(content))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -210,66 +180,13 @@ Blocktrans With Count And Plural
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(blocktranslate_group
|
(blocktranslate_group
|
||||||
(blocktrans_block
|
variable: (identifier)
|
||||||
(blocktrans_tag
|
(filtered_value
|
||||||
variable: (identifier)
|
(value
|
||||||
(filtered_value
|
(variable_attribute
|
||||||
(value
|
(identifier))))
|
||||||
(variable_attribute
|
(content)
|
||||||
(identifier)))))
|
(content))
|
||||||
(content)
|
|
||||||
(plural_block
|
|
||||||
(plural_tag)
|
|
||||||
(content)))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Blocktrans With An Empty Singular
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% blocktrans count n=x %}{% plural %}many{% endblocktrans %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(blocktranslate_group
|
|
||||||
(blocktrans_block
|
|
||||||
(blocktrans_tag
|
|
||||||
variable: (identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(plural_block
|
|
||||||
(plural_tag)
|
|
||||||
(content)))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Blocktranslate With An Empty Plural
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% blocktranslate count n=x %}one{% plural %}{% endblocktranslate %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(blocktranslate_group
|
|
||||||
(blocktranslate_block
|
|
||||||
(blocktranslate_tag
|
|
||||||
variable: (identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(content)
|
|
||||||
(plural_block
|
|
||||||
(plural_tag)))
|
|
||||||
(endblocktranslate_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -283,28 +200,23 @@ Blocktrans With Every Option
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(blocktranslate_group
|
(blocktranslate_group
|
||||||
(blocktrans_block
|
variable: (identifier)
|
||||||
(blocktrans_tag
|
(filtered_value
|
||||||
variable: (identifier)
|
(value
|
||||||
(filtered_value
|
(variable_attribute
|
||||||
(value
|
(identifier))))
|
||||||
(variable_attribute
|
variable: (identifier)
|
||||||
(identifier))))
|
(filtered_value
|
||||||
variable: (identifier)
|
(value
|
||||||
(filtered_value
|
(variable_attribute
|
||||||
(value
|
(identifier))))
|
||||||
(variable_attribute
|
(filtered_value
|
||||||
(identifier))))
|
(value
|
||||||
(filtered_value
|
(literal
|
||||||
(value
|
(string))))
|
||||||
(literal
|
asvar: (identifier)
|
||||||
(string))))
|
(content)
|
||||||
asvar: (identifier))
|
(content))
|
||||||
(content)
|
|
||||||
(plural_block
|
|
||||||
(plural_tag)
|
|
||||||
(content)))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -318,11 +230,8 @@ Blocktrans With Its Options Reordered
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(blocktranslate_group
|
(blocktranslate_group
|
||||||
(blocktrans_block
|
asvar: (identifier)
|
||||||
(blocktrans_tag
|
(content))
|
||||||
asvar: (identifier))
|
|
||||||
(content))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -347,26 +256,13 @@ Blocktranslate Closed By The Other Spelling
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
Blocktrans With Count And No Plural
|
Blocktrans With Count And No Plural
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% blocktrans count n=x %}one{% endblocktrans %}
|
{% blocktrans count n=x %}one{% endblocktrans %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(blocktranslate_group
|
|
||||||
(blocktrans_block
|
|
||||||
(blocktrans_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(content)
|
|
||||||
(missing_plural_tag))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Blocktrans With Plural And No Count
|
Blocktrans With Plural And No Count
|
||||||
@@ -380,29 +276,13 @@ Blocktrans With Plural And No Count
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
Blocktrans Counting Two Bindings
|
Blocktrans Counting Two Bindings
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% blocktrans count n=x c=d %}one{% plural %}many{% endblocktrans %}
|
{% blocktrans count n=x c=d %}one{% plural %}many{% endblocktrans %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(blocktranslate_group
|
|
||||||
(blocktrans_block
|
|
||||||
(blocktrans_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content)
|
|
||||||
(plural_block
|
|
||||||
(plural_tag)
|
|
||||||
(content)))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Blocktrans With Nothing To Bind
|
Blocktrans With Nothing To Bind
|
||||||
@@ -416,21 +296,13 @@ Blocktrans With Nothing To Bind
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
Blocktrans With An Unknown Option
|
Blocktrans With An Unknown Option
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% blocktrans bogus %}hi{% endblocktrans %}
|
{% blocktrans bogus %}hi{% endblocktrans %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(blocktranslate_group
|
|
||||||
(blocktrans_block
|
|
||||||
(blocktrans_tag
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Blocktrans With Asvar And No Name
|
Blocktrans With Asvar And No Name
|
||||||
@@ -474,183 +346,82 @@ Blocktrans Holding Another Blocktrans
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
Blocktrans With Two Plurals
|
Blocktrans With Two Plurals
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% blocktrans count n=x %}one{% plural %}many{% plural %}x{% endblocktrans %}
|
{% blocktrans count n=x %}one{% plural %}many{% plural %}x{% endblocktrans %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(blocktranslate_group
|
|
||||||
(blocktrans_block
|
|
||||||
(blocktrans_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(content)
|
|
||||||
(plural_block
|
|
||||||
(plural_tag)
|
|
||||||
(content)))
|
|
||||||
(missing_endblocktrans_tag))
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Blocktrans With An Argument On Plural
|
Blocktrans With An Argument On Plural
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% blocktrans count n=x %}one{% plural extra %}many{% endblocktrans %}
|
{% blocktrans count n=x %}one{% plural extra %}many{% endblocktrans %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(blocktranslate_group
|
|
||||||
(blocktrans_block
|
|
||||||
(blocktrans_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(content)
|
|
||||||
(plural_block
|
|
||||||
(plural_tag
|
|
||||||
(unexpected_argument))
|
|
||||||
(content)))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Blocktrans With Trimmed Twice
|
Blocktrans With Trimmed Twice
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% blocktrans trimmed trimmed %}hi{% endblocktrans %}
|
{% blocktrans trimmed trimmed %}hi{% endblocktrans %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(blocktranslate_group
|
|
||||||
(blocktrans_block
|
|
||||||
(blocktrans_tag
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Blocktrans With With Twice
|
Blocktrans With With Twice
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% blocktrans with a=b with c=d %}hi{% endblocktrans %}
|
{% blocktrans with a=b with c=d %}hi{% endblocktrans %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(blocktranslate_group
|
|
||||||
(blocktrans_block
|
|
||||||
(blocktrans_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Blocktrans With Context Twice
|
Blocktrans With Context Twice
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% blocktrans context "a" context "b" %}hi{% endblocktrans %}
|
{% blocktrans context "a" context "b" %}hi{% endblocktrans %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(blocktranslate_group
|
|
||||||
(blocktrans_block
|
|
||||||
(blocktrans_tag
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(string))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Blocktrans With Asvar Twice
|
Blocktrans With Asvar Twice
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% blocktrans asvar x asvar y %}hi{% endblocktrans %}
|
{% blocktrans asvar x asvar y %}hi{% endblocktrans %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(blocktranslate_group
|
|
||||||
(blocktrans_block
|
|
||||||
(blocktrans_tag
|
|
||||||
(identifier)
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Blocktrans With Count Twice
|
Blocktrans With Count Twice
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% blocktrans count n=x count m=y %}a{% plural %}b{% endblocktrans %}
|
{% blocktrans count n=x count m=y %}a{% plural %}b{% endblocktrans %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(blocktranslate_group
|
|
||||||
(blocktrans_block
|
|
||||||
(blocktrans_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content)
|
|
||||||
(plural_block
|
|
||||||
(plural_tag)
|
|
||||||
(content)))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Blocktranslate With Trimmed Twice
|
Blocktranslate With Trimmed Twice
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% blocktranslate trimmed trimmed %}hi{% endblocktranslate %}
|
{% blocktranslate trimmed trimmed %}hi{% endblocktranslate %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(blocktranslate_group
|
|
||||||
(blocktranslate_block
|
|
||||||
(blocktranslate_tag
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
(endblocktranslate_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Blocktrans Repeating An Option Of The Tag Before It
|
Blocktrans Repeating An Option Of The Tag Before It
|
||||||
@@ -663,36 +434,16 @@ Blocktrans Repeating An Option Of The Tag Before It
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(blocktranslate_group
|
(blocktranslate_group
|
||||||
(blocktrans_block
|
(content))
|
||||||
(blocktrans_tag)
|
|
||||||
(content))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(blocktranslate_group
|
(blocktranslate_group
|
||||||
(blocktrans_block
|
(content))
|
||||||
(blocktrans_tag)
|
|
||||||
(content))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Blocktrans With A Binding Twice
|
Blocktrans With A Binding Twice
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% blocktrans with a=1 a=2 %}x{% endblocktrans %}
|
{% blocktrans with a=1 a=2 %}x{% endblocktrans %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(blocktranslate_group
|
|
||||||
(blocktrans_block
|
|
||||||
(blocktrans_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
(endblocktrans_tag))
|
|
||||||
(content))
|
|
||||||
+84
-119
@@ -9,16 +9,14 @@ Cache
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(cache_group
|
(cache_group
|
||||||
(cache_block
|
(cache_clause
|
||||||
(cache_tag
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(number))))
|
||||||
(number))))
|
(identifier)
|
||||||
(identifier))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endcache_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -32,16 +30,14 @@ Cache With A Variable Timeout
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(cache_group
|
(cache_group
|
||||||
(cache_block
|
(cache_clause
|
||||||
(cache_tag
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier))))
|
(identifier)
|
||||||
(identifier))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endcache_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -55,21 +51,19 @@ Cache With A Filtered Timeout
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(cache_group
|
(cache_group
|
||||||
(cache_block
|
(cache_clause
|
||||||
(cache_tag
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(number)))
|
||||||
(number)))
|
(filter_expression
|
||||||
(filter_expression
|
(filter
|
||||||
(filter
|
argument: (value
|
||||||
argument: (value
|
(literal
|
||||||
(literal
|
(number))))))
|
||||||
(number))))))
|
(identifier)
|
||||||
(identifier))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endcache_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -83,16 +77,14 @@ Cache With A Quoted Fragment Name
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(cache_group
|
(cache_group
|
||||||
(cache_block
|
(cache_clause
|
||||||
(cache_tag
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(number))))
|
||||||
(number))))
|
(string)
|
||||||
(string))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endcache_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -106,24 +98,22 @@ Cache Varying On Arguments
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(cache_group
|
(cache_group
|
||||||
(cache_block
|
(cache_clause
|
||||||
(cache_tag
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(number))))
|
||||||
(number))))
|
(identifier)
|
||||||
(identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier))))
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endcache_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -137,22 +127,20 @@ Cache Varying On A Filtered Argument
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(cache_group
|
(cache_group
|
||||||
(cache_block
|
(cache_clause
|
||||||
(cache_tag
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(number))))
|
||||||
(number))))
|
(identifier)
|
||||||
(identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)))
|
||||||
(identifier)))
|
(filter_expression
|
||||||
(filter_expression
|
(filter)))
|
||||||
(filter))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endcache_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -166,20 +154,18 @@ Cache Using A Named Cache
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(cache_group
|
(cache_group
|
||||||
(cache_block
|
(cache_clause
|
||||||
(cache_tag
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(number))))
|
||||||
(number))))
|
(identifier)
|
||||||
(identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(string))))
|
||||||
(string)))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endcache_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -193,20 +179,18 @@ Cache Using An Unquoted Cache Name
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(cache_group
|
(cache_group
|
||||||
(cache_block
|
(cache_clause
|
||||||
(cache_tag
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(number))))
|
||||||
(number))))
|
(identifier)
|
||||||
(identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endcache_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -221,31 +205,13 @@ Cache Without A Fragment Name
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
Cache With Anything After Using
|
Cache With Anything After Using
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% cache 500 sidebar using="c" extra %}x{% endcache %}
|
{% cache 500 sidebar using="c" extra %}x{% endcache %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(cache_group
|
|
||||||
(cache_block
|
|
||||||
(cache_tag
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number))))
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(string))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endcache_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Cache With An Empty Using
|
Cache With An Empty Using
|
||||||
@@ -275,4 +241,3 @@ Cache With Using As Its Fragment Name
|
|||||||
{% cache 500 using="c" %}x{% endcache %}
|
{% cache 500 using="c" %}x{% endcache %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
+5
-17
@@ -11,10 +11,7 @@ This is ignored
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(comment_group
|
(comment_group
|
||||||
(comment_block
|
(comment_content))
|
||||||
(comment_tag)
|
|
||||||
(comment_content))
|
|
||||||
(endcomment_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -27,10 +24,7 @@ Comment Empty
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(comment_group
|
(comment_group)
|
||||||
(comment_block
|
|
||||||
(comment_tag))
|
|
||||||
(endcomment_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -46,11 +40,8 @@ This is ignored
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(comment_group
|
(comment_group
|
||||||
(comment_block
|
(string)
|
||||||
(comment_tag
|
(comment_content))
|
||||||
(string))
|
|
||||||
(comment_content))
|
|
||||||
(endcomment_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -66,8 +57,5 @@ Contains {% if x %} tag-like text
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(comment_group
|
(comment_group
|
||||||
(comment_block
|
(comment_content))
|
||||||
(comment_tag)
|
|
||||||
(comment_content))
|
|
||||||
(endcomment_tag))
|
|
||||||
(content))
|
(content))
|
||||||
@@ -8,7 +8,7 @@ Csp Nonce Attr
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(csp_nonce_attr_tag)
|
(csp_nonce_attr)
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -21,7 +21,7 @@ Csp Nonce Attr With Argument And As
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(csp_nonce_attr_tag
|
(csp_nonce_attr
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -39,7 +39,7 @@ Csp Nonce Attr With Media Keyword
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(csp_nonce_attr_tag
|
(csp_nonce_attr
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -48,68 +48,43 @@ Csp Nonce Attr With Media Keyword
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
Csp Nonce Attr Takes One Argument
|
Csp Nonce Attr Takes One Argument
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% csp_nonce_attr "a" "b" %}
|
{% csp_nonce_attr "a" "b" %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
(ERROR)
|
||||||
(content)
|
|
||||||
(csp_nonce_attr_tag
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(string))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Csp Nonce Attr Rejects Unknown Keyword
|
Csp Nonce Attr Rejects Unknown Keyword
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% csp_nonce_attr other="b" %}
|
{% csp_nonce_attr other="b" %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
(ERROR)
|
||||||
(content)
|
|
||||||
(csp_nonce_attr_tag
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Csp Nonce Attr Rejects Repeated Keyword
|
Csp Nonce Attr Rejects Repeated Keyword
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% csp_nonce_attr media=1 media=2 %}
|
{% csp_nonce_attr media=1 media=2 %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
(ERROR)
|
||||||
(content)
|
|
||||||
(csp_nonce_attr_tag
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Csp Nonce Attr With Media Twice
|
Csp Nonce Attr With Media Twice
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% csp_nonce_attr media="a" media="b" %}
|
{% csp_nonce_attr media="a" media="b" %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(csp_nonce_attr_tag
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(string))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
@@ -10,5 +10,5 @@ Csrf Token
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(csrf_token_tag)
|
(csrf_token)
|
||||||
(content))
|
(content))
|
||||||
+19
-36
@@ -9,7 +9,7 @@ Custom Tag
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(custom_tag
|
(custom_tag
|
||||||
tag_name: (identifier))
|
tag: (identifier))
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -23,7 +23,7 @@ Custom Tag With Arguments
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(custom_tag
|
(custom_tag
|
||||||
tag_name: (identifier)
|
tag: (identifier)
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
@@ -49,7 +49,7 @@ Custom Tag With Keyword Arguments
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(custom_tag
|
(custom_tag
|
||||||
tag_name: (identifier)
|
tag: (identifier)
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
@@ -72,7 +72,7 @@ Custom Tag With As
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(custom_tag
|
(custom_tag
|
||||||
tag_name: (identifier)
|
tag: (identifier)
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
@@ -91,7 +91,7 @@ Custom Tag With Filtered Argument
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(custom_tag
|
(custom_tag
|
||||||
tag_name: (identifier)
|
tag: (identifier)
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
@@ -111,10 +111,10 @@ Custom Tag Does Not Nest
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(custom_tag
|
(custom_tag
|
||||||
tag_name: (identifier))
|
tag: (identifier))
|
||||||
(content)
|
(content)
|
||||||
(custom_tag
|
(custom_tag
|
||||||
tag_name: (identifier))
|
tag: (identifier))
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -144,7 +144,7 @@ Custom Filter
|
|||||||
(identifier)))
|
(identifier)))
|
||||||
(filter_expression
|
(filter_expression
|
||||||
(filter
|
(filter
|
||||||
filter_name: (identifier)))))
|
name: (identifier)))))
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -164,7 +164,7 @@ Custom Filter With Argument
|
|||||||
(identifier)))
|
(identifier)))
|
||||||
(filter_expression
|
(filter_expression
|
||||||
(filter
|
(filter
|
||||||
filter_name: (identifier)
|
name: (identifier)
|
||||||
argument: (value
|
argument: (value
|
||||||
(literal
|
(literal
|
||||||
(string)))))))
|
(string)))))))
|
||||||
@@ -187,7 +187,7 @@ Custom Filter In A Chain With A Builtin
|
|||||||
(identifier)))
|
(identifier)))
|
||||||
(filter_expression
|
(filter_expression
|
||||||
(filter
|
(filter
|
||||||
filter_name: (identifier))
|
name: (identifier))
|
||||||
(filter))))
|
(filter))))
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
@@ -201,14 +201,14 @@ Custom Filter In A Tag
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(firstof_tag
|
(firstof
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
(identifier)))
|
(identifier)))
|
||||||
(filter_expression
|
(filter_expression
|
||||||
(filter
|
(filter
|
||||||
filter_name: (identifier)))))
|
name: (identifier)))))
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -230,32 +230,25 @@ Builtin Filter With An Argument It Does Not Take
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Custom Tag Does Not Cover An End Tag
|
Custom Tag Does Not Cover An End Tag
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Custom Tag Does Not Cover A Part Of A Tag Group
|
Custom Tag Does Not Cover A Part Of A Tag Group
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
A Name Reserved For A Tag Is Still A Variable
|
A Name Reserved For A Tag Is Still A Variable
|
||||||
@@ -285,7 +278,7 @@ A Name Reserved For A Tag Is Still An Argument
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(custom_tag
|
(custom_tag
|
||||||
tag_name: (identifier)
|
tag: (identifier)
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
@@ -294,23 +287,13 @@ A Name Reserved For A Tag Is Still An Argument
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
Custom Tag With A Keyword Argument Twice
|
Custom Tag With A Keyword Argument Twice
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% mytag a=1 a=2 %}
|
{% mytag a=1 a=2 %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(custom_tag
|
|
||||||
(identifier)
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Custom Tag With Keyword Arguments And As
|
Custom Tag With Keyword Arguments And As
|
||||||
@@ -323,7 +306,7 @@ Custom Tag With Keyword Arguments And As
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(custom_tag
|
(custom_tag
|
||||||
tag_name: (identifier)
|
tag: (identifier)
|
||||||
(identifier)
|
(identifier)
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
@@ -348,14 +331,14 @@ Custom Tag Repeating A Keyword Of The Tag Before It
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(custom_tag
|
(custom_tag
|
||||||
tag_name: (identifier)
|
tag: (identifier)
|
||||||
(identifier)
|
(identifier)
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
(number)))))
|
(number)))))
|
||||||
(custom_tag
|
(custom_tag
|
||||||
tag_name: (identifier)
|
tag: (identifier)
|
||||||
(identifier)
|
(identifier)
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ Cycle Basic
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(cycle_tag
|
(cycle
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -35,7 +35,7 @@ Cycle With As
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(cycle_tag
|
(cycle
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -60,7 +60,7 @@ Cycle With As And Silent
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(cycle_tag
|
(cycle
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -85,7 +85,7 @@ Cycle Referencing Existing Variable
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(cycle_tag
|
(cycle
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
@@ -136,7 +136,7 @@ Cycle Spanning Lines
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(cycle_tag
|
(cycle
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
|
|||||||
@@ -10,5 +10,5 @@ Debug
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(debug_tag)
|
(debug)
|
||||||
(content))
|
(content))
|
||||||
@@ -9,7 +9,7 @@ Extends With String
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(extends_tag
|
(extends
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -27,7 +27,7 @@ Extends With Variable
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(extends_tag
|
(extends
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
|
|||||||
+14
-20
@@ -13,13 +13,11 @@ hello
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(filter_group
|
(filter_group
|
||||||
(filter_block
|
(filter_clause
|
||||||
(filter_tag
|
(filter_expression
|
||||||
(filter_expression
|
(filter))
|
||||||
(filter)))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endfilter_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -37,14 +35,12 @@ HELLO WORLD
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(filter_group
|
(filter_group
|
||||||
(filter_block
|
(filter_clause
|
||||||
(filter_tag
|
(filter_expression
|
||||||
(filter_expression
|
(filter)
|
||||||
(filter)
|
(filter))
|
||||||
(filter)))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endfilter_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -63,12 +59,10 @@ HELLO WORLD
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(filter_group
|
(filter_group
|
||||||
(filter_block
|
(filter_clause
|
||||||
(filter_tag
|
(filter_expression
|
||||||
(filter_expression
|
(filter)
|
||||||
(filter)
|
(filter))
|
||||||
(filter)))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endfilter_tag))
|
|
||||||
(content))
|
(content))
|
||||||
@@ -8,7 +8,7 @@ Firstof Basic
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(firstof_tag
|
(firstof
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
@@ -33,7 +33,7 @@ Firstof With As
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(firstof_tag
|
(firstof
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
|
|||||||
+184
-478
@@ -13,13 +13,12 @@ For Basic
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(for_group
|
(for_group
|
||||||
(for_block
|
(for_clause
|
||||||
(for_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(template_variable
|
(template_variable
|
||||||
@@ -27,8 +26,7 @@ For Basic
|
|||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
(identifier)))))
|
(identifier)))))
|
||||||
(content)))
|
(content))))
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -46,14 +44,13 @@ For With Multiple Variables
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(for_group
|
(for_group
|
||||||
(for_block
|
(for_clause
|
||||||
(for_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(template_variable
|
(template_variable
|
||||||
@@ -61,8 +58,7 @@ For With Multiple Variables
|
|||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
(identifier)))))
|
(identifier)))))
|
||||||
(content)))
|
(content))))
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -82,13 +78,12 @@ For With Empty
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(for_group
|
(for_group
|
||||||
(for_block
|
(for_clause
|
||||||
(for_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(template_variable
|
(template_variable
|
||||||
@@ -97,125 +92,9 @@ For With Empty
|
|||||||
(variable_attribute
|
(variable_attribute
|
||||||
(identifier)))))
|
(identifier)))))
|
||||||
(content)))
|
(content)))
|
||||||
(empty_block
|
(empty_clause
|
||||||
(empty_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
For Does Not Take An Else
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% for a in b %}x{% else %}y{% endfor %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
variable: (identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
For With Empty Twice
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% for a in b %}x{% empty %}y{% empty %}z{% endfor %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
variable: (identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(empty_block
|
|
||||||
(empty_tag)
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
For With An Empty Clause And No Body
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% for a in b %}{% empty %}{% endfor %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
variable: (identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(empty_block
|
|
||||||
(empty_tag))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
For With A Nested If In Its Empty Clause
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% for a in b %}x{% empty %}{% if q %}y{% endif %}{% endfor %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
variable: (identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(empty_block
|
|
||||||
(empty_tag)
|
|
||||||
(template
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endif_tag))))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -231,28 +110,24 @@ For With A Tag In Its Body
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(for_group
|
(for_group
|
||||||
(for_block
|
(for_clause
|
||||||
(for_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(if_group
|
(if_group
|
||||||
(if_block
|
(if_clause
|
||||||
(if_tag
|
(predicate
|
||||||
(predicate
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)))))
|
||||||
(identifier))))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endif_tag))
|
(content))))
|
||||||
(content)))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -268,126 +143,24 @@ For With A Nested For
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(for_group
|
(for_group
|
||||||
(for_block
|
(for_clause
|
||||||
(for_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(for_group
|
(for_group
|
||||||
(for_block
|
(for_clause
|
||||||
(for_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endfor_tag))
|
(content))))
|
||||||
(content)))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
For With A Nested With
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% for a in b %}{% with c=1 %}y{% endwith %}{% endfor %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
variable: (identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(template
|
|
||||||
(with_group
|
|
||||||
(with_block
|
|
||||||
(with_tag
|
|
||||||
variable: (identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number)))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endwith_tag))))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
For With A Cycle In Its Body
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% for a in b %}{% cycle 1 2 %}{% endfor %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
variable: (identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(template
|
|
||||||
(cycle_tag
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number))))
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number)))))))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
For With Multiple Variables And A Nested If
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% for a, b in c %}{% if x %}y{% endif %}{% endfor %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
variable: (identifier)
|
|
||||||
variable: (identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(template
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endif_tag))))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -405,44 +178,37 @@ For With Tags In Both Branches
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(for_group
|
(for_group
|
||||||
(for_block
|
(for_clause
|
||||||
(for_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(if_group
|
(if_group
|
||||||
(if_block
|
(if_clause
|
||||||
(if_tag
|
(predicate
|
||||||
(predicate
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)))))
|
||||||
(identifier))))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endif_tag))
|
|
||||||
(content)))
|
(content)))
|
||||||
(empty_block
|
(empty_clause
|
||||||
(empty_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(with_group
|
(with_group
|
||||||
(with_block
|
(with_clause
|
||||||
(with_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(number))))
|
||||||
(number)))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endwith_tag))
|
(content))))
|
||||||
(content)))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -458,25 +224,21 @@ For With A Named Block In Its Body
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(for_group
|
(for_group
|
||||||
(for_block
|
(for_clause
|
||||||
(for_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(block_group
|
(block_group
|
||||||
(block_block
|
(block_clause
|
||||||
(block_tag
|
name: (push_block)
|
||||||
name: (push_block))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content)))
|
||||||
(endblock_tag
|
(pop_block))
|
||||||
(pop_block)))
|
(content))))
|
||||||
(content)))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -492,38 +254,32 @@ For Nested In A Tag
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(if_group
|
(if_group
|
||||||
(if_block
|
(if_clause
|
||||||
(if_tag
|
(predicate
|
||||||
(predicate
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)))))
|
||||||
(identifier))))))
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(for_group
|
(for_group
|
||||||
(for_block
|
(for_clause
|
||||||
(for_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(if_group
|
(if_group
|
||||||
(if_block
|
(if_clause
|
||||||
(if_tag
|
(predicate
|
||||||
(predicate
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)))))
|
||||||
(identifier))))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content)))))))
|
||||||
(endif_tag))))
|
(content))))
|
||||||
(endfor_tag))
|
|
||||||
(content)))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -537,14 +293,12 @@ For With An Empty Body
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(for_group
|
(for_group
|
||||||
(for_block
|
(for_clause
|
||||||
(for_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))))
|
||||||
(identifier))))))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -560,16 +314,14 @@ a
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(for_group
|
(for_group
|
||||||
(for_block
|
(for_clause
|
||||||
(for_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -585,17 +337,15 @@ a
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(for_group
|
(for_group
|
||||||
(for_block
|
(for_clause
|
||||||
(for_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -611,21 +361,19 @@ a
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(for_group
|
(for_group
|
||||||
(for_block
|
(for_clause
|
||||||
(for_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)))
|
||||||
(identifier)))
|
(filter_expression
|
||||||
(filter_expression
|
(filter
|
||||||
(filter
|
argument: (value
|
||||||
argument: (value
|
(literal
|
||||||
(literal
|
(string))))))
|
||||||
(string)))))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -643,20 +391,17 @@ b
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(for_group
|
(for_group
|
||||||
(for_block
|
(for_clause
|
||||||
(for_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content)))
|
||||||
(empty_block
|
(empty_clause
|
||||||
(empty_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -672,53 +417,35 @@ For Reversed With A Tag In Its Body
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(for_group
|
(for_group
|
||||||
(for_block
|
(for_clause
|
||||||
(for_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(if_group
|
(if_group
|
||||||
(if_block
|
(if_clause
|
||||||
(if_tag
|
(predicate
|
||||||
(predicate
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)))))
|
||||||
(identifier))))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endif_tag))
|
(content))))
|
||||||
(content)))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
For With Reversed Twice
|
For With Reversed Twice
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% for x in y reversed reversed %}a{% endfor %}
|
{% for x in y reversed reversed %}a{% endfor %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
For With Reversed Before In
|
For With Reversed Before In
|
||||||
@@ -729,7 +456,6 @@ For With Reversed Before In
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
For Over A Variable Named Reversed
|
For Over A Variable Named Reversed
|
||||||
==================
|
==================
|
||||||
@@ -741,16 +467,14 @@ For Over A Variable Named Reversed
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(for_group
|
(for_group
|
||||||
(for_block
|
(for_clause
|
||||||
(for_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -764,17 +488,15 @@ For Over An Attribute Of A Variable Named Reversed
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(for_group
|
(for_group
|
||||||
(for_block
|
(for_clause
|
||||||
(for_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)
|
||||||
(identifier)
|
(attribute))))
|
||||||
(attribute)))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -788,18 +510,16 @@ For Over A Filtered Variable Named Reversed
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(for_group
|
(for_group
|
||||||
(for_block
|
(for_clause
|
||||||
(for_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)))
|
||||||
(identifier)))
|
(filter_expression
|
||||||
(filter_expression
|
(filter)))
|
||||||
(filter))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -814,24 +534,10 @@ For With Reversed As Its Whole Sequence
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
For With Reversed Three Times
|
For With Reversed Three Times
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% for x in reversed reversed reversed %}a{% endfor %}
|
{% for x in reversed reversed reversed %}a{% endfor %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
|
||||||
+32
-66
@@ -8,7 +8,7 @@ Trans
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(translate_tag
|
(translate
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -25,7 +25,7 @@ Translate
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(translate_tag
|
(translate
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -42,7 +42,7 @@ Trans With A Variable
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(translate_tag
|
(translate
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
@@ -59,7 +59,7 @@ Trans With A Filtered Message
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(translate_tag
|
(translate
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -78,7 +78,7 @@ Trans Noop
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(translate_tag
|
(translate
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -95,7 +95,7 @@ Trans With As
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(translate_tag
|
(translate
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -113,7 +113,7 @@ Trans With Context
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(translate_tag
|
(translate
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -134,7 +134,7 @@ Trans With Every Option
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(translate_tag
|
(translate
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -156,7 +156,7 @@ Trans With Its Options Reordered
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(translate_tag
|
(translate
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -180,21 +180,13 @@ Trans Without A Message
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
Trans With An Option Twice
|
Trans With An Option Twice
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% trans "hi" noop noop %}
|
{% trans "hi" noop noop %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(translate_tag
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(string))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Trans With As Twice
|
Trans With As Twice
|
||||||
@@ -208,21 +200,13 @@ Trans With As Twice
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
Trans With An Unknown Option
|
Trans With An Unknown Option
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% trans "hi" bogus %}
|
{% trans "hi" bogus %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(translate_tag
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(string))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Trans With Context And No Value
|
Trans With Context And No Value
|
||||||
@@ -244,7 +228,7 @@ Get Available Languages
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(get_available_languages_tag
|
(get_available_languages
|
||||||
variable: (identifier))
|
variable: (identifier))
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
@@ -268,7 +252,7 @@ Get Current Language
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(get_current_language_tag
|
(get_current_language
|
||||||
variable: (identifier))
|
variable: (identifier))
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
@@ -282,7 +266,7 @@ Get Current Language Bidi
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(get_current_language_bidi_tag
|
(get_current_language_bidi
|
||||||
variable: (identifier))
|
variable: (identifier))
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
@@ -296,7 +280,7 @@ Get Language Info
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(get_language_info_tag
|
(get_language_info
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -314,7 +298,7 @@ Get Language Info For A Variable
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(get_language_info_tag
|
(get_language_info
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
@@ -352,7 +336,7 @@ Get Language Info List
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(get_language_info_list_tag
|
(get_language_info_list
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
@@ -371,15 +355,13 @@ Language
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(language_group
|
(language_group
|
||||||
(language_block
|
(language_clause
|
||||||
(language_tag
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(string))))
|
||||||
(string)))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endlanguage_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -393,15 +375,13 @@ Language With A Variable
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(language_group
|
(language_group
|
||||||
(language_block
|
(language_clause
|
||||||
(language_tag
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endlanguage_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -416,26 +396,13 @@ Language Without An Argument
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
Language With Two Arguments
|
Language With Two Arguments
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% language "a" "b" %}x{% endlanguage %}
|
{% language "a" "b" %}x{% endlanguage %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(language_group
|
|
||||||
(language_block
|
|
||||||
(language_tag
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(string))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endlanguage_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Language Name Filter
|
Language Name Filter
|
||||||
@@ -522,7 +489,6 @@ Language Name Filter With An Argument
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Translate With A Context Named After Noop
|
Translate With A Context Named After Noop
|
||||||
:error
|
:error
|
||||||
@@ -543,7 +509,7 @@ Translate With A Context From An Attribute Of Noop
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(translate_tag
|
(translate
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -565,7 +531,7 @@ Translate With A Filtered Context Named After Noop
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(translate_tag
|
(translate
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
|
|||||||
+152
-323
@@ -11,17 +11,15 @@ Hi
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(if_group
|
(if_group
|
||||||
(if_block
|
(if_clause
|
||||||
(if_tag
|
(predicate
|
||||||
(predicate
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)
|
||||||
(identifier)
|
(attribute)))))
|
||||||
(attribute))))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endif_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -37,16 +35,14 @@ working
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(if_group
|
(if_group
|
||||||
(if_block
|
(if_clause
|
||||||
(if_tag
|
(predicate
|
||||||
(predicate
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)))))
|
||||||
(identifier))))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endif_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -66,186 +62,35 @@ other
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(if_group
|
(if_group
|
||||||
(if_block
|
(if_clause
|
||||||
(if_tag
|
(predicate
|
||||||
(predicate
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier))))
|
(binaryOperator)
|
||||||
(binaryOperator)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(number)))))
|
||||||
(number))))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content)))
|
||||||
(elif_block
|
(elif_clause
|
||||||
(elif_tag
|
(predicate
|
||||||
(predicate
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier))))
|
(binaryOperator)
|
||||||
(binaryOperator)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(number)))))
|
||||||
(number))))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content)))
|
||||||
(else_block
|
(else_clause
|
||||||
(else_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endif_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
If With Elif
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if x %}a{% elif y %}b{% endif %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(elif_block
|
|
||||||
(elif_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
If With Else
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if x %}a{% else %}b{% endif %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(else_block
|
|
||||||
(else_tag)
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
If With An Elif Missing Its Condition
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if x %}a{% elif %}b{% endif %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
If With An Elif After An Else
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if x %}a{% else %}b{% elif y %}c{% endif %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)))
|
|
||||||
(elif_block
|
|
||||||
(elif_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
If With Two Elses
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if x %}a{% else %}b{% else %}c{% endif %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(else_block
|
|
||||||
(else_tag)
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -261,48 +106,46 @@ yes
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(if_group
|
(if_group
|
||||||
(if_block
|
(if_clause
|
||||||
(if_tag
|
(predicate
|
||||||
(predicate
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier))))
|
(binaryOperator)
|
||||||
(binaryOperator)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier))))
|
(binaryOperator)
|
||||||
(binaryOperator)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier))))
|
(binaryOperator)
|
||||||
(binaryOperator)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier))))
|
(binaryOperator)
|
||||||
(binaryOperator)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier))))
|
(binaryOperator)
|
||||||
(binaryOperator)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)))
|
||||||
(identifier)))
|
(filter_expression
|
||||||
(filter_expression
|
(filter)))
|
||||||
(filter)))
|
(binaryOperator)
|
||||||
(binaryOperator)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(number)))))
|
||||||
(number))))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endif_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -325,21 +168,19 @@ If Is Not None
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(if_group
|
(if_group
|
||||||
(if_block
|
(if_clause
|
||||||
(if_tag
|
(predicate
|
||||||
(predicate
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier))))
|
(binaryOperator)
|
||||||
(binaryOperator)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(none)))))
|
||||||
(none))))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endif_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -353,21 +194,19 @@ If Is
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(if_group
|
(if_group
|
||||||
(if_block
|
(if_clause
|
||||||
(if_tag
|
(predicate
|
||||||
(predicate
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier))))
|
(binaryOperator)
|
||||||
(binaryOperator)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)))))
|
||||||
(identifier))))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endif_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -381,21 +220,19 @@ If Is Not
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(if_group
|
(if_group
|
||||||
(if_block
|
(if_clause
|
||||||
(if_tag
|
(predicate
|
||||||
(predicate
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier))))
|
(binaryOperator)
|
||||||
(binaryOperator)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)))))
|
||||||
(identifier))))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endif_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -409,21 +246,19 @@ If Is Not Not
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(if_group
|
(if_group
|
||||||
(if_block
|
(if_clause
|
||||||
(if_tag
|
(predicate
|
||||||
(predicate
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier))))
|
(binaryOperator)
|
||||||
(binaryOperator)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)))))
|
||||||
(identifier))))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endif_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -437,16 +272,14 @@ If With A Repeated Not
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(if_group
|
(if_group
|
||||||
(if_block
|
(if_clause
|
||||||
(if_tag
|
(predicate
|
||||||
(predicate
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)))))
|
||||||
(identifier))))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endif_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -460,16 +293,14 @@ If Not Before A Name Beginning With In
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(if_group
|
(if_group
|
||||||
(if_block
|
(if_clause
|
||||||
(if_tag
|
(predicate
|
||||||
(predicate
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)))))
|
||||||
(identifier))))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endif_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -483,19 +314,17 @@ If Is Before A Name Beginning With Not
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(if_group
|
(if_group
|
||||||
(if_block
|
(if_clause
|
||||||
(if_tag
|
(predicate
|
||||||
(predicate
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier))))
|
(binaryOperator)
|
||||||
(binaryOperator)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)))))
|
||||||
(identifier))))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endif_tag))
|
|
||||||
(content))
|
(content))
|
||||||
+38
-85
@@ -11,11 +11,9 @@ content
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(ifchanged_group
|
(ifchanged_group
|
||||||
(ifchanged_block
|
(ifchanged_clause
|
||||||
(ifchanged_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endifchanged_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -31,19 +29,17 @@ content
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(ifchanged_group
|
(ifchanged_group
|
||||||
(ifchanged_block
|
(ifchanged_clause
|
||||||
(ifchanged_tag
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier))))
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endifchanged_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -61,15 +57,12 @@ unchanged
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(ifchanged_group
|
(ifchanged_group
|
||||||
(ifchanged_block
|
(ifchanged_clause
|
||||||
(ifchanged_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content)))
|
||||||
(else_block
|
(else_clause
|
||||||
(else_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endifchanged_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -87,25 +80,22 @@ unchanged
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(ifchanged_group
|
(ifchanged_group
|
||||||
(ifchanged_block
|
(ifchanged_clause
|
||||||
(ifchanged_tag
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier))))
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)))
|
||||||
(identifier)))
|
(filter_expression
|
||||||
(filter_expression
|
(filter)))
|
||||||
(filter))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content)))
|
||||||
(else_block
|
(else_clause
|
||||||
(else_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endifchanged_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -121,13 +111,10 @@ content
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(ifchanged_group
|
(ifchanged_group
|
||||||
(ifchanged_block
|
(ifchanged_clause
|
||||||
(ifchanged_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content)))
|
||||||
(else_block
|
(else_clause))
|
||||||
(else_tag))
|
|
||||||
(endifchanged_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -149,30 +136,25 @@ c
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(ifchanged_group
|
(ifchanged_group
|
||||||
(ifchanged_block
|
(ifchanged_clause
|
||||||
(ifchanged_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content)))
|
||||||
(else_block
|
(else_clause
|
||||||
(else_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(ifchanged_group
|
(ifchanged_group
|
||||||
(ifchanged_block
|
(ifchanged_clause
|
||||||
(ifchanged_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content)))
|
||||||
(else_block
|
(else_clause
|
||||||
(else_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endifchanged_tag))
|
(content))))
|
||||||
(content)))
|
|
||||||
(endifchanged_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Ifchanged With Two Elses
|
Ifchanged With Two Elses
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% ifchanged %}
|
{% ifchanged %}
|
||||||
@@ -185,24 +167,10 @@ c
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(ifchanged_group
|
|
||||||
(ifchanged_block
|
|
||||||
(ifchanged_tag)
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(else_block
|
|
||||||
(else_tag)
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)))
|
|
||||||
(endifchanged_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Ifchanged With An Argument On Else
|
Ifchanged With An Argument On Else
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% ifchanged %}
|
{% ifchanged %}
|
||||||
@@ -212,18 +180,3 @@ b
|
|||||||
{% endifchanged %}
|
{% endifchanged %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(ifchanged_group
|
|
||||||
(ifchanged_block
|
|
||||||
(ifchanged_tag)
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(else_block
|
|
||||||
(else_tag
|
|
||||||
(unexpected_argument))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endifchanged_tag))
|
|
||||||
(content))
|
|
||||||
+13
-64
@@ -8,7 +8,7 @@ Include With String
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(include_tag
|
(include
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -25,7 +25,7 @@ Include With Variable
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(include_tag
|
(include
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
@@ -42,7 +42,7 @@ Include With A Filtered Name
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(include_tag
|
(include
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -61,7 +61,7 @@ Include Only
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(include_tag
|
(include
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -78,7 +78,7 @@ Include With Context
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(include_tag
|
(include
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -100,7 +100,7 @@ Include With Several Bindings
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(include_tag
|
(include
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -127,7 +127,7 @@ Include With Context And Only
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(include_tag
|
(include
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -149,7 +149,7 @@ Include With Only Before With
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(include_tag
|
(include
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -163,26 +163,13 @@ Include With Only Before With
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
Include With A Binding Twice
|
Include With A Binding Twice
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% include "t.html" with a=1 a=2 %}
|
{% include "t.html" with a=1 a=2 %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(include_tag
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(string))))
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Include Without A Name
|
Include Without A Name
|
||||||
@@ -206,62 +193,33 @@ Include With Nothing To Bind
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
Include With With Twice
|
Include With With Twice
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% include "t.html" with a=1 with b=2 %}
|
{% include "t.html" with a=1 with b=2 %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(include_tag
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(string))))
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Include With Only Twice
|
Include With Only Twice
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% include "t.html" only only %}
|
{% include "t.html" only only %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(include_tag
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(string))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Include With An Unknown Option
|
Include With An Unknown Option
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% include "t.html" bogus %}
|
{% include "t.html" bogus %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(include_tag
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(string))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Include With A Legacy Binding
|
Include With A Legacy Binding
|
||||||
@@ -275,18 +233,9 @@ Include With A Legacy Binding
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
Include With A Second Name
|
Include With A Second Name
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% include "t.html" "u.html" %}
|
{% include "t.html" "u.html" %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(include_tag
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(string))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
+14
-52
@@ -9,11 +9,9 @@ Localize
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(localize_group
|
(localize_group
|
||||||
(localize_block
|
(localize_clause
|
||||||
(localize_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endlocalize_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -27,11 +25,9 @@ Localize On
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(localize_group
|
(localize_group
|
||||||
(localize_block
|
(localize_clause
|
||||||
(localize_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endlocalize_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -45,11 +41,9 @@ Localize Off
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(localize_group
|
(localize_group
|
||||||
(localize_block
|
(localize_clause
|
||||||
(localize_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endlocalize_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -63,11 +57,9 @@ Localize Hugging Its Delimiters
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(localize_group
|
(localize_group
|
||||||
(localize_block
|
(localize_clause
|
||||||
(localize_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endlocalize_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -81,72 +73,43 @@ Localize Nested
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(localize_group
|
(localize_group
|
||||||
(localize_block
|
(localize_clause
|
||||||
(localize_tag)
|
|
||||||
(template
|
(template
|
||||||
(localize_group
|
(localize_group
|
||||||
(localize_block
|
(localize_clause
|
||||||
(localize_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content)))))))
|
||||||
(endlocalize_tag))))
|
|
||||||
(endlocalize_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Localize With Another Argument
|
Localize With Another Argument
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% localize maybe %}x{% endlocalize %}
|
{% localize maybe %}x{% endlocalize %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(localize_group
|
|
||||||
(localize_block
|
|
||||||
(localize_tag
|
|
||||||
(unexpected_argument))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endlocalize_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Localize With Two Arguments
|
Localize With Two Arguments
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% localize on off %}x{% endlocalize %}
|
{% localize on off %}x{% endlocalize %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(localize_group
|
|
||||||
(localize_block
|
|
||||||
(localize_tag
|
|
||||||
(unexpected_argument))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endlocalize_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Localize Unclosed
|
Localize Unclosed
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% localize %}
|
{% localize %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(localize_group
|
|
||||||
(localize_block
|
|
||||||
(localize_tag)
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(missing_endlocalize_tag)))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Localize Filter
|
Localize Filter
|
||||||
@@ -204,4 +167,3 @@ Unlocalize Filter With An Argument
|
|||||||
{{ x|unlocalize:1 }}
|
{{ x|unlocalize:1 }}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ Load Single Library
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(load_tag
|
(load
|
||||||
(library
|
(library
|
||||||
(identifier)))
|
(identifier)))
|
||||||
(content))
|
(content))
|
||||||
@@ -23,7 +23,7 @@ Load Multiple Libraries
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(load_tag
|
(load
|
||||||
(library
|
(library
|
||||||
(identifier))
|
(identifier))
|
||||||
(library
|
(library
|
||||||
@@ -40,7 +40,7 @@ Load Dotted Library
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(load_tag
|
(load
|
||||||
(library
|
(library
|
||||||
(identifier)
|
(identifier)
|
||||||
(identifier)))
|
(identifier)))
|
||||||
@@ -56,7 +56,7 @@ Load Names From Library
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(load_tag
|
(load
|
||||||
(identifier)
|
(identifier)
|
||||||
(identifier)
|
(identifier)
|
||||||
(library
|
(library
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ Lorem Words
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(lorem_tag
|
(lorem
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -25,7 +25,7 @@ Lorem Paragraphs Random
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(lorem_tag
|
(lorem
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
|
|||||||
@@ -1,992 +0,0 @@
|
|||||||
==================
|
|
||||||
Missing Endif At End Of Input
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if a %}x
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(missing_endif_tag)))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Missing Endfor After Empty
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% for x in y %}a{% empty %}b
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(empty_block
|
|
||||||
(empty_tag)
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(missing_endfor_tag)))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Missing Endblock At End Of Input
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% block content %}x
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(block_group
|
|
||||||
(block_block
|
|
||||||
(block_tag
|
|
||||||
(push_block))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(missing_endblock_tag)))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Missing Endpartialdef At End Of Input
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% partialdef p %}x
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(partialdef_group
|
|
||||||
(partialdef_block
|
|
||||||
(partialdef_tag
|
|
||||||
(push_partial))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(missing_endpartialdef_tag)))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Missing Endverbatim With An Empty Body
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% verbatim %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(verbatim_group
|
|
||||||
(verbatim_block
|
|
||||||
(verbatim_tag
|
|
||||||
(push_verbatim))
|
|
||||||
(verbatim_content))
|
|
||||||
(missing_endverbatim_tag)))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Missing Endverbatim After A Tag In Its Text
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% verbatim %}{% endif %}x
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(verbatim_group
|
|
||||||
(verbatim_block
|
|
||||||
(verbatim_tag
|
|
||||||
(push_verbatim))
|
|
||||||
(verbatim_content))
|
|
||||||
(missing_endverbatim_tag)))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Missing Endcomment At End Of Input
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% comment %}x
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(comment_group
|
|
||||||
(comment_block
|
|
||||||
(comment_tag)
|
|
||||||
(comment_content))
|
|
||||||
(missing_endcomment_tag)))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Missing Endif Before An Outer End Tag
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% for x in y %}{% if a %}{% endfor %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(template
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))))
|
|
||||||
(missing_endif_tag))))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Unseen Outer Else Is Not A Missing Tag
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if a %}{% for x in y %}{% else %}b{% endif %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(template
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)))
|
|
||||||
(missing_endfor_tag))))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Missing Endwith Before An Outer Endblock
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% block a %}{% with b=1 %}{% endblock a %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(block_group
|
|
||||||
(block_block
|
|
||||||
(block_tag
|
|
||||||
(push_block))
|
|
||||||
(template
|
|
||||||
(with_group
|
|
||||||
(with_block
|
|
||||||
(with_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number))))))
|
|
||||||
(missing_endwith_tag))))
|
|
||||||
(endblock_tag
|
|
||||||
(pop_block)))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Missing Two End Tags At End Of Input
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% for x in y %}{% if a %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(template
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(missing_endif_tag))))
|
|
||||||
(missing_endfor_tag)))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Missing Endblock Before An Outer Name
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% block a %}{% block b %}{% endblock a %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(block_group
|
|
||||||
(block_block
|
|
||||||
(block_tag
|
|
||||||
(push_block))
|
|
||||||
(template
|
|
||||||
(block_group
|
|
||||||
(block_block
|
|
||||||
(block_tag
|
|
||||||
(push_block)))
|
|
||||||
(missing_endblock_tag))))
|
|
||||||
(endblock_tag
|
|
||||||
(pop_block)))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Missing Endpartialdef Before An Outer Name
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% partialdef a %}{% partialdef b %}{% endpartialdef a %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(partialdef_group
|
|
||||||
(partialdef_block
|
|
||||||
(partialdef_tag
|
|
||||||
(push_partial))
|
|
||||||
(template
|
|
||||||
(partialdef_group
|
|
||||||
(partialdef_block
|
|
||||||
(partialdef_tag
|
|
||||||
(push_partial)))
|
|
||||||
(missing_endpartialdef_tag))))
|
|
||||||
(endpartialdef_tag
|
|
||||||
(pop_partial)))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Missing Plural At End Of Input
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% blocktrans count n=x %}one
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(blocktranslate_group
|
|
||||||
(blocktrans_block
|
|
||||||
(blocktrans_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(content)
|
|
||||||
(missing_plural_tag))
|
|
||||||
(missing_endblocktrans_tag)))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Missing Plural Before Endblocktranslate
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% blocktranslate count n=x %}one{% endblocktranslate %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(blocktranslate_group
|
|
||||||
(blocktranslate_block
|
|
||||||
(blocktranslate_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(content)
|
|
||||||
(missing_plural_tag))
|
|
||||||
(endblocktranslate_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Missing Endblocktrans After Plural
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% blocktrans count n=x %}one{% plural %}many
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(blocktranslate_group
|
|
||||||
(blocktrans_block
|
|
||||||
(blocktrans_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(content)
|
|
||||||
(plural_block
|
|
||||||
(plural_tag)
|
|
||||||
(content)))
|
|
||||||
(missing_endblocktrans_tag)))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Missing Endfor Before A Tag Without Spaces
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if a %}{% for x in y %}{%endif%}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(missing_endfor_tag))))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Missing Endfor Before A Tag Across Lines
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if a %}{% for x in y %}{%
|
|
||||||
endif %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(missing_endfor_tag))))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Missing Endif After A Custom End Tag
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if a %}{% endmytag %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(custom_tag
|
|
||||||
(identifier))
|
|
||||||
(content)))
|
|
||||||
(missing_endif_tag)))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Second Else After A Nested Else Is Unexpected
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if a %}{% if b %}x{% else %}y{% else %}z{% endif %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(else_block
|
|
||||||
(else_tag)
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)))
|
|
||||||
(endif_tag))
|
|
||||||
(content)))
|
|
||||||
(missing_endif_tag)))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Second Empty After A Nested Empty Is Unexpected
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% for x in y %}{% for z in w %}a{% empty %}b{% empty %}c{% endfor %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(template
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(empty_block
|
|
||||||
(empty_tag)
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)))
|
|
||||||
(endfor_tag))
|
|
||||||
(content)))
|
|
||||||
(missing_endfor_tag)))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Else Of An If Nested In An Else
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if a %}x{% else %}{% if b %}y{% else %}z{% endif %}{% endif %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(else_block
|
|
||||||
(else_tag)
|
|
||||||
(template
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(else_block
|
|
||||||
(else_tag)
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endif_tag))))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Elif Of An If Nested In An Elif
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if a %}x{% elif b %}{% if c %}y{% elif d %}z{% endif %}{% endif %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(elif_block
|
|
||||||
(elif_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(elif_block
|
|
||||||
(elif_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endif_tag))))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Empty Of A For Nested In An Empty
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% for x in y %}a{% empty %}{% for z in w %}b{% empty %}c{% endfor %}{% endfor %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(empty_block
|
|
||||||
(empty_tag)
|
|
||||||
(template
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(empty_block
|
|
||||||
(empty_tag)
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endfor_tag))))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Else Of An Ifchanged Nested In An Else Of An If
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if a %}x{% else %}{% ifchanged %}y{% else %}z{% endifchanged %}{% endif %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(else_block
|
|
||||||
(else_tag)
|
|
||||||
(template
|
|
||||||
(ifchanged_group
|
|
||||||
(ifchanged_block
|
|
||||||
(ifchanged_tag)
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(else_block
|
|
||||||
(else_tag)
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endifchanged_tag))))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Else Of An If Nested In An Else Of An Ifchanged
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% ifchanged %}a{% else %}{% if b %}y{% else %}z{% endif %}{% endifchanged %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(ifchanged_group
|
|
||||||
(ifchanged_block
|
|
||||||
(ifchanged_tag)
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(else_block
|
|
||||||
(else_tag)
|
|
||||||
(template
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(else_block
|
|
||||||
(else_tag)
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endif_tag))))
|
|
||||||
(endifchanged_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Third Else Is Unexpected Too
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if a %}w{% else %}x{% else %}y{% else %}z{% endif %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(else_block
|
|
||||||
(else_tag)
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Second And Third Empty Are Unexpected
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% for x in y %}a{% empty %}b{% empty %}c{% empty %}d{% endfor %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(empty_block
|
|
||||||
(empty_tag)
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Second And Third Else Of An Ifchanged Are Unexpected
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% ifchanged %}a{% else %}b{% else %}c{% else %}d{% endifchanged %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(ifchanged_group
|
|
||||||
(ifchanged_block
|
|
||||||
(ifchanged_tag)
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(else_block
|
|
||||||
(else_tag)
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)))
|
|
||||||
(endifchanged_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Second Else Inside A Block Is Unexpected
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% block a %}{% if b %}x{% else %}y{% else %}z{% endif %}{% endblock %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(block_group
|
|
||||||
(block_block
|
|
||||||
(block_tag
|
|
||||||
(push_block))
|
|
||||||
(template
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(else_block
|
|
||||||
(else_tag)
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)))
|
|
||||||
(endif_tag))))
|
|
||||||
(endblock_tag
|
|
||||||
(pop_block)))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Second Else Of An If In A For Is Unexpected
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% for x in y %}{% if a %}b{% else %}c{% else %}d{% endif %}{% endfor %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(for_group
|
|
||||||
(for_block
|
|
||||||
(for_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))
|
|
||||||
(template
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(else_block
|
|
||||||
(else_tag)
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)))
|
|
||||||
(endif_tag))))
|
|
||||||
(endfor_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Stray End Tag After A Missing One
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if a %}{% endfor %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)))
|
|
||||||
(missing_endif_tag)))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Endblock Naming No Open Block
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% block a %}{% block b %}{% endblock c %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(block_group
|
|
||||||
(block_block
|
|
||||||
(block_tag
|
|
||||||
(push_block))
|
|
||||||
(template
|
|
||||||
(block_group
|
|
||||||
(block_block
|
|
||||||
(block_tag
|
|
||||||
(push_block))
|
|
||||||
(template
|
|
||||||
(unexpected_tag
|
|
||||||
(unexpected_argument))
|
|
||||||
(content)))
|
|
||||||
(missing_endblock_tag))))
|
|
||||||
(missing_endblock_tag)))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Second Else Is Not A Missing Tag
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if a %}{% else %}{% else %}{% endif %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier)))))))
|
|
||||||
(else_block
|
|
||||||
(else_tag)
|
|
||||||
(template
|
|
||||||
(unexpected_tag)))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Plural Without Count Is Not A Missing Tag
|
|
||||||
:error
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% blocktrans %}one{% plural %}many{% endblocktrans %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
+2
-2
@@ -8,7 +8,7 @@ Now Basic
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(now_tag
|
(now
|
||||||
(string))
|
(string))
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ Now With As
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(now_tag
|
(now
|
||||||
(string)
|
(string)
|
||||||
variable: (identifier))
|
variable: (identifier))
|
||||||
(content))
|
(content))
|
||||||
@@ -8,6 +8,6 @@ Partial Basic
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(partial_tag
|
(partial
|
||||||
(identifier))
|
(identifier))
|
||||||
(content))
|
(content))
|
||||||
@@ -13,13 +13,11 @@ Partialdef Basic
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(partialdef_group
|
(partialdef_group
|
||||||
(partialdef_block
|
(partialdef_clause
|
||||||
(partialdef_tag
|
(push_partial)
|
||||||
(push_partial))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content)))
|
||||||
(endpartialdef_tag
|
(pop_partial))
|
||||||
(pop_partial)))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -37,11 +35,9 @@ Partialdef Inline
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(partialdef_group
|
(partialdef_group
|
||||||
(partialdef_block
|
(partialdef_clause
|
||||||
(partialdef_tag
|
(push_partial)
|
||||||
(push_partial))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content)))
|
||||||
(endpartialdef_tag
|
(pop_partial))
|
||||||
(pop_partial)))
|
|
||||||
(content))
|
(content))
|
||||||
@@ -8,7 +8,7 @@ Querystring Empty
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(querystring_tag)
|
(query_string)
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -21,7 +21,7 @@ Querystring With Key Value
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(querystring_tag
|
(query_string
|
||||||
(identifier)
|
(identifier)
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
@@ -39,7 +39,7 @@ Querystring With Identifier And Key Value
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(querystring_tag
|
(query_string
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
@@ -61,7 +61,7 @@ Querystring With Expression Argument And As
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(querystring_tag
|
(query_string
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
@@ -85,7 +85,7 @@ Querystring With Two Keys
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(querystring_tag
|
(query_string
|
||||||
(identifier)
|
(identifier)
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
@@ -100,43 +100,19 @@ Querystring With Two Keys
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
Querystring With A Key Twice
|
Querystring With A Key Twice
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% querystring page=2 page=3 %}
|
{% querystring page=2 page=3 %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(querystring_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Querystring With A Key Repeated Later
|
Querystring With A Key Repeated Later
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% querystring a=1 b=2 a=3 %}
|
{% querystring a=1 b=2 a=3 %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(querystring_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number))))
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
@@ -8,7 +8,7 @@ Regroup Basic
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(regroup_tag
|
(regroup
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ Resetcycle Bare
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(resetcycle_tag)
|
(reset_cycle)
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -21,6 +21,6 @@ Resetcycle With Name
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(resetcycle_tag
|
(reset_cycle
|
||||||
(identifier))
|
(identifier))
|
||||||
(content))
|
(content))
|
||||||
@@ -13,9 +13,7 @@ Spaceless Basic
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(spaceless_group
|
(spaceless_group
|
||||||
(spaceless_block
|
(spaceless_clause
|
||||||
(spaceless_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endspaceless_tag))
|
|
||||||
(content))
|
(content))
|
||||||
+12
-33
@@ -8,7 +8,7 @@ Static
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(static_tag
|
(static
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -25,7 +25,7 @@ Static With A Variable Path
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(static_tag
|
(static
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
@@ -42,7 +42,7 @@ Static With A Filtered Path
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(static_tag
|
(static
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -61,7 +61,7 @@ Static With As
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(static_tag
|
(static
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
@@ -81,40 +81,23 @@ Static Without A Path
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
Static With A Second Path
|
Static With A Second Path
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% static "a.css" "b.css" %}
|
{% static "a.css" "b.css" %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(static_tag
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(string))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Static With Anything After As
|
Static With Anything After As
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% static "a.css" as url junk %}
|
{% static "a.css" as url junk %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(static_tag
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(string))))
|
|
||||||
(identifier)
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Get Static Prefix
|
Get Static Prefix
|
||||||
@@ -126,7 +109,7 @@ Get Static Prefix
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(get_static_prefix_tag)
|
(get_static_prefix)
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -139,7 +122,7 @@ Get Static Prefix With As
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(get_static_prefix_tag
|
(get_static_prefix
|
||||||
variable: (identifier))
|
variable: (identifier))
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
@@ -153,23 +136,19 @@ Get Media Prefix With As
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(get_media_prefix_tag
|
(get_media_prefix
|
||||||
variable: (identifier))
|
variable: (identifier))
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Get Static Prefix Without As
|
Get Static Prefix Without As
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% get_static_prefix prefix %}
|
{% get_static_prefix prefix %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(get_static_prefix_tag
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Get Static Prefix Without A Variable
|
Get Static Prefix Without A Variable
|
||||||
@@ -191,10 +170,10 @@ Load Names The Library, Not The Tag
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(load_tag
|
(load
|
||||||
(library
|
(library
|
||||||
(identifier)))
|
(identifier)))
|
||||||
(static_tag
|
(static
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
(literal
|
(literal
|
||||||
|
|||||||
@@ -461,227 +461,3 @@ Template Variable Attribute Of A Literal
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
==================
|
|
||||||
Template Variable Trailing Dot With An Exponent
|
|
||||||
==================
|
|
||||||
|
|
||||||
{{ 1.e5 }}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(template_variable
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number)))))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Template Variable Trailing Dot
|
|
||||||
:error
|
|
||||||
==================
|
|
||||||
|
|
||||||
{{ 1. }}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
==================
|
|
||||||
Template Variable Signed Trailing Dot
|
|
||||||
:error
|
|
||||||
==================
|
|
||||||
|
|
||||||
{{ -1. }}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
==================
|
|
||||||
Braces That Open Nothing Are Text
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if x %}Hello {} world{% endif %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
A Brace Before A Tag Is Text
|
|
||||||
==================
|
|
||||||
|
|
||||||
Hello {{% if x %}a{% endif %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
A Brace Before A Comment Is Text
|
|
||||||
==================
|
|
||||||
|
|
||||||
a{{# c #}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(template_comment)
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
A Brace At The End Is Text
|
|
||||||
==================
|
|
||||||
|
|
||||||
a{
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
A Brace Before The End Tag Of A Group Is Text
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% if x %}Hello {{% endif %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
Three Braces Open A Variable
|
|
||||||
:error
|
|
||||||
==================
|
|
||||||
|
|
||||||
a{{{ x }}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
==================
|
|
||||||
A Filter Pipe With No Filter Stays In Its Variable
|
|
||||||
==================
|
|
||||||
|
|
||||||
{{ oops| }}
|
|
||||||
{% if x == 1 %}
|
|
||||||
hello
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(template_variable
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))
|
|
||||||
(ERROR))
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))
|
|
||||||
(binaryOperator)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
A Variable Missing Its Close Ends Where It Cannot Continue
|
|
||||||
==================
|
|
||||||
|
|
||||||
{{ hello }{% if display %}body {% endif %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(template_variable
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))
|
|
||||||
(missing_variable_close))
|
|
||||||
(content)
|
|
||||||
(if_group
|
|
||||||
(if_block
|
|
||||||
(if_tag
|
|
||||||
(predicate
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endif_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
A Variable Missing Its Close At The End
|
|
||||||
==================
|
|
||||||
|
|
||||||
{{ hello
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(template_variable
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(variable_attribute
|
|
||||||
(identifier))))
|
|
||||||
(missing_variable_close)))
|
|
||||||
@@ -8,7 +8,7 @@ Templatetag Openblock
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(templatetag_tag)
|
(template_tag_block)
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -21,5 +21,5 @@ Templatetag Closevariable
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(templatetag_tag)
|
(template_tag_block)
|
||||||
(content))
|
(content))
|
||||||
+31
-80
@@ -9,11 +9,9 @@ Localtime
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(localtime_group
|
(localtime_group
|
||||||
(localtime_block
|
(localtime_clause
|
||||||
(localtime_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endlocaltime_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -27,11 +25,9 @@ Localtime On
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(localtime_group
|
(localtime_group
|
||||||
(localtime_block
|
(localtime_clause
|
||||||
(localtime_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endlocaltime_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -45,50 +41,30 @@ Localtime Off
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(localtime_group
|
(localtime_group
|
||||||
(localtime_block
|
(localtime_clause
|
||||||
(localtime_tag)
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endlocaltime_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Localtime With Another Argument
|
Localtime With Another Argument
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% localtime maybe %}x{% endlocaltime %}
|
{% localtime maybe %}x{% endlocaltime %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(localtime_group
|
|
||||||
(localtime_block
|
|
||||||
(localtime_tag
|
|
||||||
(unexpected_argument))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endlocaltime_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Localtime With Two Arguments
|
Localtime With Two Arguments
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% localtime on off %}x{% endlocaltime %}
|
{% localtime on off %}x{% endlocaltime %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(localtime_group
|
|
||||||
(localtime_block
|
|
||||||
(localtime_tag
|
|
||||||
(unexpected_argument))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endlocaltime_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Timezone
|
Timezone
|
||||||
@@ -101,15 +77,13 @@ Timezone
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(timezone_group
|
(timezone_group
|
||||||
(timezone_block
|
(timezone_clause
|
||||||
(timezone_tag
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(string))))
|
||||||
(string)))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endtimezone_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -123,15 +97,13 @@ Timezone With A Variable
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(timezone_group
|
(timezone_group
|
||||||
(timezone_block
|
(timezone_clause
|
||||||
(timezone_tag
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier))))
|
||||||
(identifier)))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endtimezone_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -145,17 +117,15 @@ Timezone With A Filtered Argument
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(timezone_group
|
(timezone_group
|
||||||
(timezone_block
|
(timezone_clause
|
||||||
(timezone_tag
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)))
|
||||||
(identifier)))
|
(filter_expression
|
||||||
(filter_expression
|
(filter)))
|
||||||
(filter))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endtimezone_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -170,26 +140,13 @@ Timezone Without An Argument
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
Timezone With Two Arguments
|
Timezone With Two Arguments
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% timezone "a" "b" %}x{% endtimezone %}
|
{% timezone "a" "b" %}x{% endtimezone %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(timezone_group
|
|
||||||
(timezone_block
|
|
||||||
(timezone_tag
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(string))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endtimezone_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Get Current Timezone
|
Get Current Timezone
|
||||||
@@ -201,7 +158,7 @@ Get Current Timezone
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(get_current_timezone_tag
|
(get_current_timezone
|
||||||
variable: (identifier))
|
variable: (identifier))
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
@@ -217,18 +174,13 @@ Get Current Timezone Without As
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
Get Current Timezone With Anything After As
|
Get Current Timezone With Anything After As
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% get_current_timezone as tz junk %}
|
{% get_current_timezone as tz junk %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(get_current_timezone_tag
|
|
||||||
(identifier)
|
|
||||||
(unexpected_argument))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Localtime Filter
|
Localtime Filter
|
||||||
@@ -308,4 +260,3 @@ Localtime Filter With An Argument
|
|||||||
{{ x|localtime:1 }}
|
{{ x|localtime:1 }}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
+4
-4
@@ -8,7 +8,7 @@ Url Basic
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(url_tag
|
(url_block
|
||||||
(string))
|
(string))
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ Url With Positional Args
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(url_tag
|
(url_block
|
||||||
(string)
|
(string)
|
||||||
(filtered_value
|
(filtered_value
|
||||||
(value
|
(value
|
||||||
@@ -44,7 +44,7 @@ Url With Keyword Args
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(url_tag
|
(url_block
|
||||||
(string)
|
(string)
|
||||||
(identifier)
|
(identifier)
|
||||||
(filtered_value
|
(filtered_value
|
||||||
@@ -63,7 +63,7 @@ Url With As
|
|||||||
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(url_tag
|
(url_block
|
||||||
(string)
|
(string)
|
||||||
variable: (identifier))
|
variable: (identifier))
|
||||||
(content))
|
(content))
|
||||||
+14
-29
@@ -9,12 +9,9 @@ Verbatim Basic
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(verbatim_group
|
(verbatim_group
|
||||||
(verbatim_block
|
(push_verbatim)
|
||||||
(verbatim_tag
|
(verbatim_content)
|
||||||
(push_verbatim))
|
(pop_verbatim))
|
||||||
(verbatim_content))
|
|
||||||
(endverbatim_tag
|
|
||||||
(pop_verbatim)))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -28,11 +25,8 @@ Verbatim Empty
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(verbatim_group
|
(verbatim_group
|
||||||
(verbatim_block
|
(push_verbatim)
|
||||||
(verbatim_tag
|
(pop_verbatim))
|
||||||
(push_verbatim)))
|
|
||||||
(endverbatim_tag
|
|
||||||
(pop_verbatim)))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -49,12 +43,9 @@ Verbatim Ignores Tags
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(verbatim_group
|
(verbatim_group
|
||||||
(verbatim_block
|
(push_verbatim)
|
||||||
(verbatim_tag
|
(verbatim_content)
|
||||||
(push_verbatim))
|
(pop_verbatim))
|
||||||
(verbatim_content))
|
|
||||||
(endverbatim_tag
|
|
||||||
(pop_verbatim)))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -68,12 +59,9 @@ Verbatim With Name
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(verbatim_group
|
(verbatim_group
|
||||||
(verbatim_block
|
(push_verbatim)
|
||||||
(verbatim_tag
|
(verbatim_content)
|
||||||
(push_verbatim))
|
(pop_verbatim))
|
||||||
(verbatim_content))
|
|
||||||
(endverbatim_tag
|
|
||||||
(pop_verbatim)))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -89,10 +77,7 @@ Avoid template rendering via the {% verbatim %}{% endverbatim %} block.
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(verbatim_group
|
(verbatim_group
|
||||||
(verbatim_block
|
(push_verbatim)
|
||||||
(verbatim_tag
|
(verbatim_content)
|
||||||
(push_verbatim))
|
(pop_verbatim))
|
||||||
(verbatim_content))
|
|
||||||
(endverbatim_tag
|
|
||||||
(pop_verbatim)))
|
|
||||||
(content))
|
(content))
|
||||||
+43
-111
@@ -11,14 +11,13 @@ With Basic
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(with_group
|
(with_group
|
||||||
(with_block
|
(with_clause
|
||||||
(with_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(variable_attribute
|
||||||
(variable_attribute
|
(identifier)
|
||||||
(identifier)
|
(attribute))))
|
||||||
(attribute)))))
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(template_variable
|
(template_variable
|
||||||
@@ -26,8 +25,7 @@ With Basic
|
|||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
(identifier)))))
|
(identifier)))))
|
||||||
(content)))
|
(content))))
|
||||||
(endwith_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -43,18 +41,17 @@ With Multiple Variables
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(with_group
|
(with_group
|
||||||
(with_block
|
(with_clause
|
||||||
(with_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(number))))
|
||||||
(number))))
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(number))))
|
||||||
(number)))))
|
|
||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(template_variable
|
(template_variable
|
||||||
@@ -62,87 +59,28 @@ With Multiple Variables
|
|||||||
(value
|
(value
|
||||||
(variable_attribute
|
(variable_attribute
|
||||||
(identifier)))))
|
(identifier)))))
|
||||||
(content)))
|
(content))))
|
||||||
(endwith_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
|
||||||
With Does Not Take An Else
|
|
||||||
==================
|
|
||||||
|
|
||||||
{% with x=1 %}a{% else %}b{% endwith %}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(with_group
|
|
||||||
(with_block
|
|
||||||
(with_tag
|
|
||||||
variable: (identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number)))))
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(unexpected_tag)
|
|
||||||
(content)))
|
|
||||||
(endwith_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
With A Binding Twice
|
With A Binding Twice
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% with a=1 a=2 %}x{% endwith %}
|
{% with a=1 a=2 %}x{% endwith %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(with_group
|
|
||||||
(with_block
|
|
||||||
(with_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endwith_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
With A Binding Repeated Later
|
With A Binding Repeated Later
|
||||||
|
:error
|
||||||
==================
|
==================
|
||||||
|
|
||||||
{% with a=1 b=2 a=3 %}x{% endwith %}
|
{% with a=1 b=2 a=3 %}x{% endwith %}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(template
|
|
||||||
(content)
|
|
||||||
(with_group
|
|
||||||
(with_block
|
|
||||||
(with_tag
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number))))
|
|
||||||
(identifier)
|
|
||||||
(filtered_value
|
|
||||||
(value
|
|
||||||
(literal
|
|
||||||
(number))))
|
|
||||||
(unexpected_argument))
|
|
||||||
(template
|
|
||||||
(content)))
|
|
||||||
(endwith_tag))
|
|
||||||
(content))
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
With Repeating A Binding Of The Tag Before It
|
With Repeating A Binding Of The Tag Before It
|
||||||
@@ -155,27 +93,23 @@ With Repeating A Binding Of The Tag Before It
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(with_group
|
(with_group
|
||||||
(with_block
|
(with_clause
|
||||||
(with_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(number))))
|
||||||
(number)))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endwith_tag))
|
|
||||||
(with_group
|
(with_group
|
||||||
(with_block
|
(with_clause
|
||||||
(with_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(number))))
|
||||||
(number)))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endwith_tag))
|
|
||||||
(content))
|
(content))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
@@ -189,14 +123,12 @@ With A Binding Named After A Literal
|
|||||||
(template
|
(template
|
||||||
(content)
|
(content)
|
||||||
(with_group
|
(with_group
|
||||||
(with_block
|
(with_clause
|
||||||
(with_tag
|
variable: (identifier)
|
||||||
variable: (identifier)
|
(filtered_value
|
||||||
(filtered_value
|
(value
|
||||||
(value
|
(literal
|
||||||
(literal
|
(number))))
|
||||||
(number)))))
|
|
||||||
(template
|
(template
|
||||||
(content)))
|
(content))))
|
||||||
(endwith_tag))
|
|
||||||
(content))
|
(content))
|
||||||
+10
-21
@@ -6,22 +6,21 @@
|
|||||||
"camelcase": "django",
|
"camelcase": "django",
|
||||||
"title": "Django Parser",
|
"title": "Django Parser",
|
||||||
"scope": "source.django",
|
"scope": "source.django",
|
||||||
"file-types": [
|
"file-types": ["html", "txt", "md"],
|
||||||
"html",
|
|
||||||
"txt",
|
|
||||||
"md"
|
|
||||||
],
|
|
||||||
"highlights": "queries/highlights.scm",
|
|
||||||
"injections": "queries/injections.scm",
|
|
||||||
"locals": "queries/locals.scm",
|
|
||||||
"injection-regex": "^django$",
|
"injection-regex": "^django$",
|
||||||
"class-name": "TreeSitterDjango"
|
"class-name": "TreeSitterDjango",
|
||||||
|
"highlights": "queries/highlights.scm",
|
||||||
|
"locals": "queries/locals.scm",
|
||||||
|
"injections": "queries/injections.scm"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"bindings": {
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"version": "0.1.2",
|
"version": "0.0.1",
|
||||||
|
"description": "DJango grammar for tree-sitter",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "Django grammar for tree-sitter",
|
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "Daniel Hanson",
|
"name": "Daniel Hanson",
|
||||||
@@ -31,15 +30,5 @@
|
|||||||
"links": {
|
"links": {
|
||||||
"repository": "https://github.com/danhanson/tree-sitter-django"
|
"repository": "https://github.com/danhanson/tree-sitter-django"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"bindings": {
|
|
||||||
"c": true,
|
|
||||||
"go": true,
|
|
||||||
"java": false,
|
|
||||||
"node": true,
|
|
||||||
"python": true,
|
|
||||||
"rust": true,
|
|
||||||
"swift": true,
|
|
||||||
"zig": false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user