diff --git a/docs/themes/navy/layout/partial/all-contributors.swig b/docs/themes/navy/layout/partial/all-contributors.swig index 64804020fc..1524163497 100644 --- a/docs/themes/navy/layout/partial/all-contributors.swig +++ b/docs/themes/navy/layout/partial/all-contributors.swig @@ -67,6 +67,7 @@ BaNgan Mahyar Pasarzangene Tomáš Hübelbauer + Jason Garber diff --git a/src/parser/tokenizer.spec.ts b/src/parser/tokenizer.spec.ts index f66f803563..4719ad5d77 100644 --- a/src/parser/tokenizer.spec.ts +++ b/src/parser/tokenizer.spec.ts @@ -199,15 +199,6 @@ describe('Tokenizer', function () { }) }) describe('#readTagToken()', () => { - it('should skip quoted delimiters', function () { - const html = '{% assign a = "%} {% }} {{" %}' - const tokenizer = new Tokenizer(html) - const token = tokenizer.readTagToken() - - expect(token).toBeInstanceOf(TagToken) - expect(token.name).toBe('assign') - expect(token.args).toBe('a = "%} {% }} {{"') - }) }) describe('#readOutputToken()', () => { it('should skip quoted delimiters', function () { diff --git a/src/parser/tokenizer.ts b/src/parser/tokenizer.ts index 5e69b11d71..87d3ca0a50 100644 --- a/src/parser/tokenizer.ts +++ b/src/parser/tokenizer.ts @@ -140,9 +140,10 @@ export class Tokenizer { return token } - readToDelimiter (delimiter: string) { + readToDelimiter (delimiter: string, respectQuoted = false) { + this.skipBlank() while (this.p < this.N) { - if ((this.peekType() & QUOTE)) { + if (respectQuoted && (this.peekType() & QUOTE)) { this.readQuoted() continue } @@ -156,7 +157,7 @@ export class Tokenizer { const { file, input } = this const { outputDelimiterRight } = options const begin = this.p - if (this.readToDelimiter(outputDelimiterRight) === -1) { + if (this.readToDelimiter(outputDelimiterRight, true) === -1) { throw this.error(`output ${this.snapshot(begin)} not closed`, begin) } return new OutputToken(input, begin, this.p, options, file) diff --git a/test/e2e/issues.spec.ts b/test/e2e/issues.spec.ts index 268911c278..24895a5f61 100644 --- a/test/e2e/issues.spec.ts +++ b/test/e2e/issues.spec.ts @@ -431,4 +431,27 @@ describe('Issues', function () { const fn = () => engine.parseAndRenderSync("{%- assign module = '' | split '' -%}") expect(fn).toThrow(/expected ":" after filter name/) }) + it('#628 Single or double quote breaks comments', () => { + const template = `{%- liquid + # Show a message that's customized to the product type + + assign product_type = product.type | downcase + assign message = '' + + case product_type + when 'health' + assign message = 'This is a health potion!' + when 'love' + assign message = 'This is a love potion!' + else + assign message = 'This is a potion!' + endcase + + echo message +-%}` + const engine = new Liquid() + const product = { type: 'love' } + const result = engine.parseAndRenderSync(template, { product }) + expect(result).toEqual('This is a love potion!') + }) }) diff --git a/test/integration/tags/inline-comment.spec.ts b/test/integration/tags/inline-comment.spec.ts index cb1d272f78..5f81e60406 100644 --- a/test/integration/tags/inline-comment.spec.ts +++ b/test/integration/tags/inline-comment.spec.ts @@ -17,6 +17,16 @@ describe('tags/inline-comment', function () { const html = await liquid.parseAndRender(src) return expect(html).toBe('foo') }) + it('should allow single quotes', async function () { + const src = "B{% # that's %}A" + const html = await liquid.parseAndRender(src) + return expect(html).toBe('BA') + }) + it('should allow double quotes', async function () { + const src = 'B{% # that"s %}A' + const html = await liquid.parseAndRender(src) + return expect(html).toBe('BA') + }) it('should handle hash without trailing whitespace', async function () { const src = '{% #some comment %}' const html = await liquid.parseAndRender(src)