Skip to content

Commit ba370d4

Browse files
committed
Update grammar to strip whitespace using Ohm matcher
1 parent 9edbe0a commit ba370d4

File tree

3 files changed

+39
-61
lines changed

3 files changed

+39
-61
lines changed

packages/liquid-html-parser/grammar/liquid-html.ohm

+11-4
Original file line numberDiff line numberDiff line change
@@ -394,11 +394,18 @@ LiquidDoc <: Helpers {
394394
| paramNode
395395
| fallbackNode
396396

397-
fallbackNode = "@" anyExceptStar<newline>
398-
paramNode = "@param" space* paramType? space* paramName (space* "-")? paramDescription
399-
paramType = "{" anyExceptStar<"}"> "}"
397+
//By default, space matches new lines as well. We override it here to make writing rules easier.
398+
strictSpace = " " | "\t"
399+
// We use this as an escape hatch to stop matching TextNode and try again when one of these characters is encountered
400+
openControl:= "@" | end
401+
402+
fallbackNode = "@" anyExceptStar<endOfParam>
403+
paramNode = "@param" strictSpace* paramType? strictSpace* paramName (strictSpace* "-")? strictSpace* paramDescription
404+
paramType = "{" strictSpace* paramTypeContent strictSpace* "}"
405+
paramTypeContent = anyExceptStar<("}"| strictSpace)>
400406
paramName = identifierCharacter+
401-
paramDescription = anyExceptStar<(newline | end)>
407+
paramDescription = anyExceptStar<endOfParam>
408+
endOfParam = strictSpace* (newline | end)
402409
}
403410

404411
LiquidHTML <: Liquid {

packages/liquid-html-parser/src/stage-1-cst.spec.ts

+5-7
Original file line numberDiff line numberDiff line change
@@ -1048,13 +1048,13 @@ describe('Unit: Stage 1 (CST)', () => {
10481048

10491049
expectPath(cst, '0.children.0.paramType.type').to.equal('TextNode');
10501050
expectPath(cst, '0.children.0.paramType.value').to.equal('String');
1051-
expectPath(cst, '0.children.0.paramType.locStart').to.equal(testStr.indexOf('{String}'));
1051+
expectPath(cst, '0.children.0.paramType.locStart').to.equal(testStr.indexOf('String'));
10521052
expectPath(cst, '0.children.0.paramType.locEnd').to.equal(
1053-
testStr.indexOf('{String}') + '{String}'.length,
1053+
testStr.indexOf('String') + 'String'.length,
10541054
);
10551055
});
10561056

1057-
it('should parse @param with type with space inside', () => {
1057+
it('should strip whitespace around param type for @param annotation', () => {
10581058
const testStr = `{% doc %} @param { String } paramWithType {% enddoc %}`;
10591059
cst = toCST(testStr);
10601060

@@ -1063,11 +1063,9 @@ describe('Unit: Stage 1 (CST)', () => {
10631063

10641064
expectPath(cst, '0.children.0.paramType.type').to.equal('TextNode');
10651065
expectPath(cst, '0.children.0.paramType.value').to.equal('String');
1066-
expectPath(cst, '0.children.0.paramType.locStart').to.equal(
1067-
testStr.indexOf('{ String }'),
1068-
);
1066+
expectPath(cst, '0.children.0.paramType.locStart').to.equal(testStr.indexOf('String'));
10691067
expectPath(cst, '0.children.0.paramType.locEnd').to.equal(
1070-
testStr.indexOf('{ String }') + '{ String }'.length,
1068+
testStr.indexOf('String') + 'String'.length,
10711069
);
10721070
});
10731071

packages/liquid-html-parser/src/stage-1-cst.ts

+23-50
Original file line numberDiff line numberDiff line change
@@ -441,15 +441,14 @@ export interface ConcreteYamlFrontmatterNode
441441

442442
export type LiquidHtmlConcreteNode =
443443
| ConcreteHtmlNode
444-
| ConcreteLiquidNode
445-
| ConcreteTextNode
446444
| ConcreteYamlFrontmatterNode
447-
| LiquidDocConcreteNode;
445+
| LiquidConcreteNode;
448446

449447
export type LiquidConcreteNode =
450448
| ConcreteLiquidNode
451449
| ConcreteTextNode
452-
| ConcreteYamlFrontmatterNode;
450+
| ConcreteYamlFrontmatterNode
451+
| LiquidDocConcreteNode;
453452

454453
export type LiquidHtmlCST = LiquidHtmlConcreteNode[];
455454

@@ -1317,17 +1316,22 @@ function toLiquidDocAST(source: string, matchingSource: string, offset: number)
13171316
throw new LiquidHTMLCSTParsingError(res);
13181317
}
13191318

1319+
/**
1320+
* Reusable text node type
1321+
*/
1322+
const textNode = {
1323+
type: ConcreteNodeTypes.TextNode,
1324+
value: function () {
1325+
return (this as any).sourceString;
1326+
},
1327+
locStart,
1328+
locEnd,
1329+
source,
1330+
};
1331+
13201332
const LiquidDocMappings: Mapping = {
13211333
Node: 0,
1322-
TextNode: {
1323-
type: ConcreteNodeTypes.TextNode,
1324-
value: function () {
1325-
return (this as any).sourceString;
1326-
},
1327-
locStart,
1328-
locEnd,
1329-
source,
1330-
},
1334+
TextNode: textNode,
13311335
paramNode: {
13321336
type: ConcreteNodeTypes.LiquidDocParamNode,
13331337
name: 'param',
@@ -1336,44 +1340,13 @@ function toLiquidDocAST(source: string, matchingSource: string, offset: number)
13361340
source,
13371341
paramType: 2,
13381342
paramName: 4,
1339-
paramDescription: 7,
1340-
},
1341-
paramType: {
1342-
type: ConcreteNodeTypes.TextNode,
1343-
value: function (nodes: Node[]) {
1344-
return nodes[1].sourceString.trim();
1345-
},
1346-
source,
1347-
locStart,
1348-
locEnd,
1349-
},
1350-
paramName: {
1351-
type: ConcreteNodeTypes.TextNode,
1352-
value: function (nodes: Node[]) {
1353-
return nodes[0].sourceString.trim();
1354-
},
1355-
source,
1356-
locStart,
1357-
locEnd,
1358-
},
1359-
paramDescription: {
1360-
type: ConcreteNodeTypes.TextNode,
1361-
value: function (nodes: Node[]) {
1362-
return nodes[0].sourceString.trim();
1363-
},
1364-
source,
1365-
locStart,
1366-
locEnd,
1367-
},
1368-
fallbackNode: {
1369-
type: ConcreteNodeTypes.TextNode,
1370-
value: function () {
1371-
return (this as any).sourceString.trim();
1372-
},
1373-
locStart,
1374-
locEnd,
1375-
source,
1343+
paramDescription: 8,
13761344
},
1345+
paramType: 2,
1346+
paramTypeContent: textNode,
1347+
paramName: textNode,
1348+
paramDescription: textNode,
1349+
fallbackNode: textNode,
13771350
};
13781351

13791352
return toAST(res, LiquidDocMappings);

0 commit comments

Comments
 (0)