Skip to content

Commit

Permalink
Stage 1 CST support for optional param delimiters
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesmengo committed Jan 24, 2025
1 parent 9a59a10 commit d7639ef
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 4 deletions.
5 changes: 3 additions & 2 deletions packages/liquid-html-parser/grammar/liquid-html.ohm
Original file line number Diff line number Diff line change
Expand Up @@ -400,10 +400,11 @@ LiquidDoc <: Helpers {
openControl:= "@" | end

fallbackNode = "@" anyExceptStar<endOfParam>
paramNode = "@param" strictSpace* paramType? strictSpace* "["? paramName "]"? (strictSpace* "-")? strictSpace* paramDescription
paramNode = "@param" strictSpace* paramType? strictSpace* paramName (strictSpace* "-")? strictSpace* paramDescription
paramType = "{" strictSpace* paramTypeContent strictSpace* "}"
paramTypeContent = anyExceptStar<("}"| strictSpace)>
paramName = identifierCharacter+
paramName = "["? strictSpace* paramNameContent strictSpace* "]"?
paramNameContent = identifierCharacter+
paramDescription = anyExceptStar<endOfParam>
endOfParam = strictSpace* (newline | end)
}
Expand Down
69 changes: 68 additions & 1 deletion packages/liquid-html-parser/src/stage-1-cst.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1011,11 +1011,12 @@ describe('Unit: Stage 1 (CST)', () => {
expectPath(cst, '0.children.0.value').to.equal('@param');
});

it('should parse @param with name', () => {
it('should parse required @param with name', () => {
const testStr = `{% doc %} @param paramWithNoDescription {% enddoc %}`;
cst = toCST(testStr);

expectPath(cst, '0.children.0.type').to.equal('LiquidDocParamNode');
expectPath(cst, '0.children.0.required').to.equal(true);
expectPath(cst, '0.children.0.paramName.type').to.equal('TextNode');
expectPath(cst, '0.children.0.paramName.value').to.equal('paramWithNoDescription');
expectPath(cst, '0.children.0.paramName.locStart').to.equal(
Expand All @@ -1028,6 +1029,72 @@ describe('Unit: Stage 1 (CST)', () => {
expectPath(cst, '0.children.0.paramDescription.value').to.equal('');
});

it('should parse an optional @param', () => {
const testStr = `{% doc %}
@param [paramWithNoDescription]
@param [ paramWithWhitespace ]
{% enddoc %}`;
cst = toCST(testStr);

expectPath(cst, '0.children.0.type').to.equal('LiquidDocParamNode');
expectPath(cst, '0.children.0.required').to.equal(false);
expectPath(cst, '0.children.0.paramName.type').to.equal('TextNode');
expectPath(cst, '0.children.0.paramName.value').to.equal('paramWithNoDescription');
expectPath(cst, '0.children.0.paramName.locStart').to.equal(
testStr.indexOf('paramWithNoDescription'),
);
expectPath(cst, '0.children.0.paramName.locEnd').to.equal(
testStr.indexOf('paramWithNoDescription') + 'paramWithNoDescription'.length,
);
expectPath(cst, '0.children.0.paramDescription.type').to.equal('TextNode');
expectPath(cst, '0.children.0.paramDescription.value').to.equal('');

expectPath(cst, '0.children.1.type').to.equal('LiquidDocParamNode');
expectPath(cst, '0.children.1.required').to.equal(false);
expectPath(cst, '0.children.1.paramName.type').to.equal('TextNode');
expectPath(cst, '0.children.1.paramName.value').to.equal('paramWithWhitespace');
expectPath(cst, '0.children.1.paramName.locStart').to.equal(
testStr.indexOf('paramWithWhitespace'),
);
expectPath(cst, '0.children.1.paramName.locEnd').to.equal(
testStr.indexOf('paramWithWhitespace') + 'paramWithWhitespace'.length,
);
});

it('should parse @param with missing optional delimiters as required', () => {
const testStr = `{% doc %}
@param paramWithMissingHeadDelim]
@param [paramWithMissingTailDelim
{% enddoc %}`;
cst = toCST(testStr);

expectPath(cst, '0.children.0.type').to.equal('LiquidDocParamNode');
expectPath(cst, '0.children.0.required').to.equal(true);
expectPath(cst, '0.children.0.paramName.type').to.equal('TextNode');
expectPath(cst, '0.children.0.paramName.value').to.equal('paramWithMissingHeadDelim');
expectPath(cst, '0.children.0.paramName.locStart').to.equal(
testStr.indexOf('paramWithMissingHeadDelim'),
);
expectPath(cst, '0.children.0.paramName.locEnd').to.equal(
testStr.indexOf('paramWithMissingHeadDelim') + 'paramWithMissingHeadDelim'.length,
);
expectPath(cst, '0.children.0.paramDescription.type').to.equal('TextNode');
expectPath(cst, '0.children.0.paramDescription.value').to.equal('');

expectPath(cst, '0.children.1.type').to.equal('LiquidDocParamNode');
expectPath(cst, '0.children.1.required').to.equal(true);
expectPath(cst, '0.children.1.paramName.type').to.equal('TextNode');
expectPath(cst, '0.children.1.paramName.value').to.equal('paramWithMissingTailDelim');
expectPath(cst, '0.children.1.paramName.locStart').to.equal(
testStr.indexOf('paramWithMissingTailDelim'),
);
expectPath(cst, '0.children.1.paramName.locEnd').to.equal(
testStr.indexOf('paramWithMissingTailDelim') + 'paramWithMissingTailDelim'.length,
);
expectPath(cst, '0.children.1.paramDescription.type').to.equal('TextNode');
expectPath(cst, '0.children.1.paramDescription.value').to.equal('');
});

it('should parse @param with name and description', () => {
const testStr = `{% doc %} @param paramWithDescription param with description {% enddoc %}`;
cst = toCST(testStr);
Expand Down
10 changes: 9 additions & 1 deletion packages/liquid-html-parser/src/stage-1-cst.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export interface ConcreteLiquidDocParamNode
paramName: ConcreteTextNode;
paramDescription: ConcreteTextNode | null;
paramType: ConcreteTextNode | null;
required: boolean;
}

export interface ConcreteHtmlNodeBase<T> extends ConcreteBasicNode<T> {
Expand Down Expand Up @@ -1341,10 +1342,17 @@ function toLiquidDocAST(source: string, matchingSource: string, offset: number)
paramType: 2,
paramName: 4,
paramDescription: 8,
required: function (nodes: Node[]) {
const paramName = nodes[4];
return (
paramName.children[0].sourceString === '' || paramName.children[4].sourceString === ''
);
},
},
paramType: 2,
paramTypeContent: textNode,
paramName: textNode,
paramName: 2,
paramNameContent: textNode,
paramDescription: textNode,
fallbackNode: textNode,
};
Expand Down

0 comments on commit d7639ef

Please sign in to comment.