From d4b047b4d89bcc302f50f079ba189b0ad0ccb91b Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 12 Mar 2020 13:58:01 -0400 Subject: [PATCH] (docs) rename to `mode_reference`; docs for callbacks - I can never find this file because it's name didn't fully match. - rename callbacks to `on:begin` and `on:end` --- CHANGES.md | 13 +++++++++ docs/index.rst | 2 +- docs/language-guide.rst | 2 +- docs/{reference.rst => mode-reference.rst} | 34 ++++++++++++++++++++-- src/highlight.js | 16 +++++----- src/lib/mode_compiler.js | 4 ++- src/lib/modes.js | 4 +-- 7 files changed, 60 insertions(+), 15 deletions(-) rename docs/{reference.rst => mode-reference.rst} (86%) diff --git a/CHANGES.md b/CHANGES.md index 9c7eda553b..b5f7f6b497 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,13 +1,26 @@ ## Version 10.1.0 (in progress) +Parser Engine: + +- (enh) Added `on:begin` callback for modes (#2261) [Josh Goebel][] +- (enh) Added `on:end` callback for modes (#2261) [Josh Goebel][] +- (enh) Added ability to programatically ignore begin and end matches (#2261) [Josh Goebel][] +- (enh) Added `END_SAME_AS_BEGIN` mode to replace `endSameAsBegin` parser attribute (#2261) [Josh Goebel][] + +Deprecations: + +- (deprecation) `endSameAsBegin` is now deprecated. (#2261) [Josh Goebel][] + Language Improvements: +- fix(cpp) Fix highlighting of unterminated raw strings (#2261) [David Benjamin][] - fix(javascript) `=>` function with nested `()` in params now works (#2502) [Josh Goebel][] - fix(typescript) `=>` function with nested `()` in params now works (#2502) [Josh Goebel][] - fix(yaml) Fix tags to include non-word characters (#2486) [Peter Plantinga][] [Josh Goebel]: https://github.com/yyyc514 [Peter Plantinga]: https://github.com/pplantinga +[David Benjamin]: https://github.com/davidben ## Version 10.0.1 diff --git a/docs/index.rst b/docs/index.rst index 3792e16245..7ae5b1953f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -13,7 +13,7 @@ Contents: api language-guide - reference + mode-reference css-classes-reference style-guide plugin-api diff --git a/docs/language-guide.rst b/docs/language-guide.rst index 0971524e52..4ed26d2d96 100644 --- a/docs/language-guide.rst +++ b/docs/language-guide.rst @@ -186,7 +186,7 @@ For such modes ``className`` attribute should be omitted so they won't generate Mode attributes --------------- -Other useful attributes are defined in the :doc:`mode reference `. +Other useful attributes are defined in the :doc:`mode reference `. .. _relevance: diff --git a/docs/reference.rst b/docs/mode-reference.rst similarity index 86% rename from docs/reference.rst rename to docs/mode-reference.rst index c823b48fca..a60400d536 100644 --- a/docs/reference.rst +++ b/docs/mode-reference.rst @@ -62,6 +62,19 @@ Regular expression starting a mode. For example a single quote for strings or tw If absent, ``begin`` defaults to a regexp that matches anything, so the mode starts immediately. +on:begin +^^^^^^^^^^^ + +**type**: callback (matchData, response) + +This callback is triggered the moment a begin match is detected. ``matchData`` includes the typical regex match data; the full match, match groups, etc. The ``response`` object is used to tell the parser how it should handle the match. It can be also used to temporarily store data. + +- ``response.data`` - a simple object data store. Can be used for building more complex rules where the end rule is dependent on the content of begin, etc. +- ``response.ignoreMatch()`` - pretend as if this match never happened. The mode is not entered. Continues trying subsequent modes in the current mode's ``contains`` list + +For an example of usage see ``END_SAME_AS_BEGIN`` in ``modes.js``. + + end ^^^ @@ -79,6 +92,19 @@ Sometimes a mode can end not by itself but implicitly with its containing (paren This is achieved with :ref:`endsWithParent ` attribute. +on:end +^^^^^^^^^^^ + +**type**: callback (matchData, response) + +This callback is triggered the moment an end match is detected. ``matchData`` includes the typical regex match data; the full match, match groups, etc. The ``response`` object is used to tell the parser how it should handle the match. It can also be used to retrieve data stored from a `begin` callback. + +- ``response.data`` - a simple object data store. Can be used for building more complex rules where the end rule is dependent on the content of begin, etc. +- ``response.ignoreMatch()`` - pretend as if this match never happened. The mode is not entered. Continues trying subsequent modes in the current mode's ``contains`` list + +For an example of usage see ``END_SAME_AS_BEGIN`` in ``modes.js``. + + beginKeywords ^^^^^^^^^^^^^^^^ @@ -182,8 +208,12 @@ tell it to end the function definition after itself: .. _endSameAsBegin: -endSameAsBegin -^^^^^^^^^^^^^^ +endSameAsBegin (deprecated as of 10.1) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +**Deprecated:** *This attribute has been deprecated.* You should instead use the +``END_SAME_AS_BEGIN`` mode or use the ``on:begin`` and ``on:end`` attributes to +build more complex paired matchers. **type**: boolean diff --git a/src/highlight.js b/src/highlight.js index ca3a3d8b6a..d60330fba5 100644 --- a/src/highlight.js +++ b/src/highlight.js @@ -203,9 +203,9 @@ const HLJS = function(hljs) { let matched = regex.startsWith(mode.endRe, matchPlusRemainder); if (matched) { - if (mode["before:end"]) { + if (mode["on:end"]) { let resp = new Response(mode); - mode["before:end"](match, resp); + mode["on:end"](match, resp); if (resp.ignore) matched = false; } @@ -217,7 +217,7 @@ const HLJS = function(hljs) { return mode; } } - // even if before:end fires an `ignore` it's still possible + // even if on:end fires an `ignore` it's still possible // that we might trigger the end node because of a parent mode if (mode.endsWithParent) { return endOfMode(mode.parent, match, matchPlusRemainder); @@ -245,7 +245,7 @@ const HLJS = function(hljs) { let resp = new Response(new_mode); // first internal before callbacks, then the public ones - let beforeCallbacks = [new_mode.__beforeBegin, new_mode["before:begin"]]; + let beforeCallbacks = [new_mode.__beforeBegin, new_mode["on:begin"]]; for (let cb of beforeCallbacks) { if (!cb) continue; cb(match, resp); @@ -268,10 +268,10 @@ const HLJS = function(hljs) { } } mode = startNewMode(new_mode); - if (mode["after:begin"]) { - let resp = new Response(mode); - mode["after:begin"](match, resp); - } + // if (mode["after:begin"]) { + // let resp = new Response(mode); + // mode["after:begin"](match, resp); + // } return new_mode.returnBegin ? 0 : lexeme.length; } diff --git a/src/lib/mode_compiler.js b/src/lib/mode_compiler.js index 16dc0adbaf..e853cf2c3b 100644 --- a/src/lib/mode_compiler.js +++ b/src/lib/mode_compiler.js @@ -61,7 +61,9 @@ export function compileLanguage(language) { // eslint-disable-next-line no-undefined const i = match.findIndex((el, i) => i > 0 && el !== undefined); const matchData = this.matchIndexes[i]; - match.splice(0, i); // // trim off the extra matches + // trim off any earlier non-relevant match groups (ie, the other regex + // match groups that make up the multi-matcher) + match.splice(0, i); return Object.assign(match, matchData); } diff --git a/src/lib/modes.js b/src/lib/modes.js index 55eabb8e67..8acb8f0e51 100644 --- a/src/lib/modes.js +++ b/src/lib/modes.js @@ -121,7 +121,7 @@ export const METHOD_GUARD = { export const END_SAME_AS_BEGIN = function(mode) { return Object.assign(mode, { - 'after:begin': (m, resp) => { resp.data._beginMatch = m[1]; }, - 'before:end': (m, resp) => { if (resp.data._beginMatch !== m[1]) resp.ignoreMatch() } + 'on:begin': (m, resp) => { resp.data._beginMatch = m[1]; }, + 'on:end': (m, resp) => { if (resp.data._beginMatch !== m[1]) resp.ignoreMatch() } }); };