-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Search for matching while should be top-down not bottom-up #110
Comments
Analyzing this I am pretty sure the correct way to check the rules is from bottom to top. While rules are specifically for constructs such as MarkDown Quote Block, which becomes nested many times.
Now, with that said, I think TextMate might be detecting that the same rule is nested, and it only pulls the stack back to the point of the top most instance. This would also work for MarkDown just fine. However, this is more complicated than it sounds. If there are any other while rules between the highest instance of the tested rule and the furthest down one, those have to be tested too. So, flip the stack of rules to a new pile (like currently done), starting with the bottom most while rule (now on the top of the while stack), test if it matches, if not, search the remaining flipped stack for the furthest down instance of the same rule, and if found, pull the main stack back to this point and keep only the top of the flipped stack above the furthest instance, then resume testing the flipped stack, else (if no further instance found) pull the stack back to this point and return. I think I have a working demonstration of this concept now. |
Find the highest instance of the rejected while rule, and return the rule stack to that condition. Otherwise nested while rules simply wipe themselves out starting with the lowest rule. Fix microsoft#110
Find the highest instance of the rejected while rule, and return the rule stack to that condition. Otherwise nested while rules simply wipe themselves out starting with the lowest rule. Fix microsoft#110
Find the highest instance of the rejected while rule, and return the rule stack to that condition. Otherwise nested while rules simply wipe themselves out starting with the lowest rule. Fix microsoft#110
Find the highest instance of the rejected while rule, and return the rule stack to that condition. Otherwise nested while rules simply wipe themselves out starting with the lowest rule. Fix microsoft#110
For more history on the topic, see previous issue #25. @mjbvz, do you have any input on this issue or the PR #111? referring back to #25:
By nothing more than analytical thinking, I am suspecting its actually:
|
Find the highest instance of the rejected while rule, and return the rule stack to that condition. Otherwise nested while rules simply wipe themselves out starting with the lowest rule. Fix microsoft#110
Find the highest instance of the rejected while rule, and return the rule stack to that condition. Otherwise nested while rules simply wipe themselves out starting with the lowest rule. Fix microsoft#110
I've had a revelation of thought while trying to understand why VS Code displays Markdown quotes in preview differently than in the editor. Example: > one nest.
>> second nest, new paragraph.
> continues paragraph of second nest.
also continues paragraph of second nest. Actually (via GitHub):
I believe VS Code's Markdown grammar is wrong. The while rule is expecting to find additional lines starting with I think there is a chance that the I have closed PR #111 for the time being, at least until I can put more thought/testing in to whether it is correct. |
I don't know specifically how TextMate implements while rules but it would be worth exploring to see if running top-down works for our existing grammars. The key parts are:
Here more context on why we use bottom-up testing of while rules: One heavy user of You cannot implement this behavior with a simple ```js
(
``` The js grammar will consume the initial So as a first step, here's some pseudo code for how a
But that pseudo code is misleading because the js grammar itself could contains a
because that'd mean that our js grammar would still be able to leak outside of the code block (the js grammar's inner Instead, whenever we are on a new line we first want to check to see if our fenced code block has ended. That means that our pseudo code would really be more like:
And that is what testing while rules bottom-up does. We also use the bottom-up nature of while rules to implement markdown inside jsdoc comments: /**
* ```js
* 1 + 1
* ```
*/ In the above example, an outer js-doc ```js
1 + 1
``` Again, I'm not sure if we can actually change from bottom-up to top-down. I'd like to understand if it makes sense and what impact of the change would be. Would our existing approach to fenced-code blocks and jsdoc work for example? Would we need to update our grammars? Could we still prevent leaks? |
@mjbvz From what I understand the entire while stack is checked for failure each line, so a failure of a lower while rule would not be ignored. The actual check: https://github.com/microsoft/vscode-textmate/blob/master/src/grammar.ts#L703 I do agree that while rules consuming leading characters, necessitates testing the while rules needs to happen bottom-up. Textmate seems to do different less useful behavior: Example Grammar:
With the above grammar, the first block works as expected. |
Now having read some of the spec for Markdown, and having altered the blockquote rule to better behave as the spec reads, I find that Markdown does not need bottom up testing. Actually, it works better with top down, as it fixes one last detail: > first nest
first nest paragraph continued according to GitHub (which does paragraphs wrong)
In VS Code with an improved but not perfect blockquote: But if you set the testing of the rules to be top down, suddenly the issue shown above goes away. (per the inspect script anyway) Yes, the entire while rule stack needs to be tested when using top down. To be clear, the current markdown grammar may fail using the top down approach, but it technically wasn't working right anyway. I'll have to test a few other patterns listed above, including I would like to visit the sample in #25. |
Consider the below examples of markdown quoted fenced code blocks. Top down while rule will fail in the second example where the blockquoting has escaped the fenced code block, but NOT because the fence block bleeds, but because the Back to the Examples > > ~~~PowerShell
> > $a = (
> > ~~~
> > ~~~PowerShell
> $a = (
> > ~~~
|
Summary: I was able to fix everything in Markdown that I thought might have only been possible if the while conditions were tested top down. Of course, this doesn't mean any of my changes would work correctly on TextMate, Sublime or Atom. |
I believe the current behavior is the expected design. Since you can workaround the original problem , let me know if you still think we should revisit this |
Given the following grammar.
And the following test file (comments are of expected highlighting)
The 5th and 6th
test
are highlighted incorrectly as compared to TextMate.The 5th
test
is not highlighted because vscode-textmate searches from the bottom up and closes both the outer and inner begin/while rule.The 6th
test
is highlighted because the unconsumed finalendif
matches /if/.Textmate has the 5th
test
highlighted and the 6th not.The text was updated successfully, but these errors were encountered: