Repository navigation
Releases: GulomovCreative/modx-tmlanguage
Release list
v2.1.0
Added
-
Indentation rules in the language configuration. A snippet call written over
several lines now indents its properties, and the]]that closes it comes
back out level with the tag that opened it. Everything else in a template is
left where it is.This completes the move of editor support out of the extension and into the
package, and it is a change extensions should notice: the rules the extension
carried before2.0.2were"increaseIndentPattern": "\\[\\[[^\\]\\]]*$", "decreaseIndentPattern": "[^\\[\\[]*\\]\\]"
and the second one outdented any line containing
]]—[[*pagetitle]],
[[- a comment ]], a value such as&tpl=`x]]y`— because it was not
anchored to the start of the line. In a template with a field tag on every
other line, typing walked the text leftwards. ([^\]\]]was also just
[^\]]: doubling inside a character class means nothing.) The rules shipped
here are anchored, ignore]]inside backticked values, and do not treat
[[- … ]]as an opening. A new test suite re-indents a template from scratch
and requires it to come back unchanged. -
A guard that every file in the published archive uses LF. Nothing is wrong
today —2.0.2unpacks with LF throughout, and.gitattributesalready pins
the checkout — but the sibling Fenom grammar published CRLF from commits that
never contained it, and the release is cut from the same machine by the same
command. This is the check that the pinning held. It packs the package and
reads the bytes in the archive rather than in the working tree — the working
tree is what is being guarded, andnpm packpacks it verbatim — and it runs
before every publish, where the fault can actually occur.
Changed
- Folding markers stay as they are:
#region/#endregionin HTML comments.
The extension used to fold on^\s*\[\[/^\s*\]\]instead, and those
are not coming back. VS Code's marker folding is line-based — a line is either
a start or an end, never both — so a one-line tag such as[[*pagetitle]]
would open a region that never closes and swallow the next]]it found. The
same reasoning was applied in the sibling Fenom grammar.
v2.0.2
Added
- A language configuration, published alongside the grammar. It is the half of
editor support that is not colour:[[pairs with]]for bracket matching
and selection, the comment command writes[[- … ]], and backticks and quotes
close as you type. Reachable as
@gulomov/modx-tmlanguage/language-configuration.json; the grammar alone is
unchanged, so nothing already using it is affected. - The README shows what the grammar looks like. The images in
docs/are
generated from a sample template through GitHub's light and dark themes, and a
test fails when they drift. They are also the only check here that can see a
scope no theme colours — the naming and README checks confirm a scope is
well-formed and documented, not that anything styles it. - A time budget on tokenization, over deliberately awkward input. These patterns
run in the editor on every keystroke; one that backtracks catastrophically
stops the editor rather than colouring anything wrongly. - Fuzz checks over generated templates, holding three rules: markup carrying no
tag stays with the host grammar, a closed tag does not colour what follows it,
and nothing unterminated survives a blank line.
Fixed
- An unterminated property value no longer colours the rest of the file. Tags,
comments and timing tags all stopped at a blank line; the backticked value
inside a tag did not, so a single forgotten backtick left everything after it
scoped as a string — markup, other tags and all. Found by the new fuzz checks
on their first run.
v2.0.1
Changed
- Releases are published by GitHub Actions from the pushed tag, not from a
maintainer's machine. Packages published this way carry npm
provenance: the
package page states which repository, workflow and commit built the tarball,
and npm verifies that statement itself. Nothing changes in how the package is
installed or used. - Every release now gets a GitHub release with the changelog section for that
version as its body. Previously tags were pushed without one.
Internal
- Comments, test names and CI step names are in English throughout. The
repository had two languages in it depending on which file you opened; the
documentation was already English, and now the code that explains itself is
too. No behaviour changed — but the CI job names did, so branch protection
rules naming the old ones need updating.
v2.0.0
A major release for three independent reasons: the package moved to a scoped name, scope names in the grammar changed, and the package entry point changed.
Published on npm as @gulomov/modx-tmlanguage.
Migration
The package is now published as @gulomov/modx-tmlanguage. The unscoped modx-tmlanguage is deprecated and will receive no further releases. Existing installs keep working — nothing was unpublished — but they stay on 1.2.0.
npm uninstall modx-tmlanguage
npm install @gulomov/modx-tmlanguageWhat the entry point returns. On 1.1.2 or earlier, nothing changes — require(...) returns the path to the grammar file, as it always did. On 1.2.0 it returned the parsed grammar object instead; that was an accident, and the object now lives at an explicit subpath:
// 1.2.0 only
const grammar = require('modx-tmlanguage');
// 2.0.0
const grammar = require('@gulomov/modx-tmlanguage/modx.tmLanguage.json');If you wrote a theme against these scopes. Several were renamed because they did not start with a root that editors recognise, and element types were split apart. modifier.modx became support.function.modifier.modx; entity.name.modx became entity.name.type.propertyset.modx; and the single entity.name.function.modx that covered every element type is now seven distinct scopes. The README's Scopes section lists all 42.
Added
- A distinct scope for each element type. Snippets, chunks, resource fields, placeholders, system settings, links and lexicons had all shared
entity.name.function.modx; they are now separate, so a theme can colour[[*pagetitle]]differently from[[pdoResources]]. This changes colours for existing users — see the Scopes section of the README for the full list. - Tests covering MODX tags inside embedded languages — HTML attribute values,
<style>, and<script>— by loading the HTML, CSS and JavaScript grammars from Shiki. This area had never been tested. The README now documents what works there, including one limitation: a bare tag in JavaScript code is not highlighted, because the JavaScript grammar reads[[as a nested array literal. - A Scopes section in the README documenting all 42 scopes, with a test that fails if the grammar emits one the README does not mention.
- A test suite: snapshots of tokenized fixtures, behaviour tests, and consistency checks. CI runs it on Node 20, 22 and 24.
.htmas a recognised file extension, and documentation of how to associate others.CONTRIBUTING.md, issue and pull request templates.bugs,homepageandenginesin the package manifest;repository.urlin the form npm expects.
Fixed
- The package entry point returns a path again. In 1.2.0 an
exportsfield was added pointing straight at the JSON, which silently overrodemain:require(...)started returning the parsed grammar object instead of the path string it returned in 1.1.2 and earlier. Anyone doingfs.readFileSync(require(...))broke. - ESM import works. It never did: importing JSON requires a type attribute, so
importfailed withERR_IMPORT_ATTRIBUTE_MISSING— including in 1.2.0, whose whole point was to add ESM support. - Scope names that no theme recognised.
modifier.modx,entity.name.modxand several others did not start with a root that editors know, so those tokens rendered unstyled. Output modifiers were the most visible casualty. - A property with no value swallowed the markup after it.
&flag &other=`1`was read as a single property name, and with no=ahead the highlighting ran on to the next one in the file. - Numbers were highlighted in ordinary markup:
<div class="col-6" data-id="42">coloured6,42and the digits of a version string. - Comments did not close mid-line.
[[- note ]] markupcoloured the rest of the line, and an unclosed comment ran to the end of the file. - A tag inside a comment was highlighted as though it were live code.
- Unterminated tags, comments and timing tags no longer colour the rest of the file; they now stop at a blank line.
- A bare
[[inside a JavaScript or CSS string no longer opens a tag. [[*#fieldname]],&before a property name, and a doubled backtick as an escape inside a value — all three are accepted by MODX and were not recognised here.
Changed
- The package is published under the
@gulomovscope. The unscoped name is deprecated.publishConfig.accessis set topublic, because npm publishes scoped packages privately by default. - The package description and keywords were rewritten. The old description named Atom, which was discontinued two months before this repository was created, and described the package as a set of files rather than one grammar.
- The copyright holder in
LICENSEis now the package author. The file had named an unrelated company since the first commit, with a year predating the repository. - Values written without backticks (
&tpl=row) are now scoped as unquoted strings rather than left unstyled. MODX accepts them: the parser strips backticks only when they are present. - Releasing is guarded.
npm versionnow refuses to run from a branch other thanmaster, with a dirty working tree, or behind the remote — previously a release would have published whatever was checked out.
Full changelog: v1.2.0...v2.0.0
v1.2.0
Fixed
- The number pattern again — rewritten on word boundaries, with support for exponent notation (
1e-5).
Added
- An
exportsfield in the package manifest, intended to enable ESM imports.
Warning
The exports field did not work as intended. It pointed straight at the JSON file, which silently overrode main: require('modx-tmlanguage') began returning the parsed grammar object instead of the path string it had returned in 1.1.2 and earlier, so fs.readFileSync(require('modx-tmlanguage')) broke. ESM import did not work either — importing JSON requires a type attribute. Both are fixed in 2.0.0, which is published under a new name, @gulomov/modx-tmlanguage.
Full changelog: v1.1.2...v1.2.0
v1.1.2
Fixed the numeric matcher. It was \d, so every digit anywhere in the file was scoped as a number, one character at a time. It now matches whole numbers, optionally signed and fractional, and only when not adjacent to letters.
Full changelog: v1.1.1...v1.1.2
v1.1.1
scopeName changed from source.modx to text.html.modx, and the injection selector with it. source.modx moved down to the interpolation rule, so it now names MODX tags inside the document rather than the document itself.
Full changelog: v1.1.0...v1.1.1
v1.1.0
Reworked highlighting. The grammar was rewritten to a repository of named rules, introducing the scopes comment.modx, entity.name.modx, keyword.other.modx, punctuation.modx and constant.character.escape.
The package was also made public on npm and given keywords.
Full changelog: https://github.com/GulomovCreative/modx-tmlanguage/commits/v1.1.0