Skip to content
This repository has been archived by the owner on Jun 20, 2024. It is now read-only.

Commit

Permalink
Add support for ints and floats as numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
charlespwd committed Aug 2, 2022
1 parent ea54ad0 commit 96f2b11
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 11 deletions.
8 changes: 8 additions & 0 deletions grammar/liquid-html.ohm
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,19 @@ LiquidHTML {
// TODO
liquidLiteral =
| liquidString
| liquidNumber

liquidString = liquidSingleQuotedString | liquidDoubleQuotedString
liquidSingleQuotedString = "'" anyExceptStar<("'"| "%}" | "}}")> "'"
liquidDoubleQuotedString = "\"" anyExceptStar<("\""| "%}" | "}}")> "\""

liquidNumber = liquidFloat | liquidInteger
liquidInteger = "-"? digit+

// This rule is funky (because of the possibility of many periods), but that's
// coming from shopify/liquid...
liquidFloat = "-"? digit (digit | ".")+

// https://www.w3.org/TR/2011/WD-html-markup-20110113/syntax.html#void-element
// Cheating a bit with by stretching it to the doctype
voidElementName =
Expand Down
21 changes: 21 additions & 0 deletions src/parser/ast.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,27 @@ describe('Unit: toLiquidHtmlAST', () => {
expectPosition(ast, 'children.0.markup.expression');
});
});

it('should parse numbers as LiquidVariable > Number', () => {
[
{ expression: `1`, value: '1' },
{ expression: `1.02`, value: '1.02' },
{ expression: `0`, value: '0' },
{ expression: `-0`, value: '-0' },
{ expression: `-0.0`, value: '-0.0' },
].forEach(({ expression, value }) => {
ast = toLiquidHtmlAST(`{{ ${expression} }}`);
expectPath(ast, 'children.0').to.exist;
expectPath(ast, 'children.0.type').to.eql('LiquidDrop');
expectPath(ast, 'children.0.markup.type').to.eql('LiquidVariable');
expectPath(ast, 'children.0.markup.rawSource').to.eql(expression);
expectPath(ast, 'children.0.markup.expression.type').to.eql('Number');
expectPath(ast, 'children.0.markup.expression.value').to.eql(value);
expectPosition(ast, 'children.0');
expectPosition(ast, 'children.0.markup');
expectPosition(ast, 'children.0.markup.expression');
});
});
});

it('should transform a basic Liquid Tag into a LiquidTag', () => {
Expand Down
35 changes: 27 additions & 8 deletions src/parser/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ interface LiquidVariable extends ASTNode<NodeTypes.LiquidVariable> {
}

// TODO
type LiquidExpression = LiquidString;
type LiquidExpression = LiquidString | LiquidNumber;

// TODO
type LiquidFilter = undefined;
Expand All @@ -140,6 +140,10 @@ interface LiquidString extends ASTNode<NodeTypes.String> {
value: string;
}

interface LiquidNumber extends ASTNode<NodeTypes.Number> {
value: string;
}

export type HtmlNode =
| HtmlComment
| HtmlElement
Expand Down Expand Up @@ -625,13 +629,28 @@ function toExpression(
node: ConcreteLiquidExpression,
source: string,
): LiquidExpression {
return {
type: NodeTypes.String,
position: position(node),
single: node.single,
value: node.value,
source,
};
switch (node.type) {
case ConcreteNodeTypes.String: {
return {
type: NodeTypes.String,
position: position(node),
single: node.single,
value: node.value,
source,
};
}
case ConcreteNodeTypes.Number: {
return {
type: NodeTypes.Number,
position: position(node),
value: node.value,
source,
};
}
default: {
return assertNever(node);
}
}
}

function toFilters(
Expand Down
22 changes: 22 additions & 0 deletions src/parser/cst.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,28 @@ describe('Unit: toLiquidHtmlCST(text)', () => {
expectLocation(cst, '0.markup.expression');
});
});

it('should parse numbers', () => {
[
{ expression: `1`, value: '1' },
{ expression: `1.02`, value: '1.02' },
{ expression: `0`, value: '0' },
{ expression: `-0`, value: '-0' },
{ expression: `-0.0`, value: '-0.0' },
].forEach(({ expression, value }) => {
cst = toLiquidHtmlCST(`{{ ${expression} }}`);
expectPath(cst, '0.type').to.equal('LiquidDrop');
expectPath(cst, '0.markup.type').to.equal('LiquidVariable');
expectPath(cst, '0.markup.rawSource').to.equal(expression);
expectPath(cst, '0.markup.expression.type').to.equal('Number');
expectPath(cst, '0.markup.expression.value').to.equal(value);
expectPath(cst, '0.whitespaceStart').to.equal(null);
expectPath(cst, '0.whitespaceEnd').to.equal(null);
expectLocation(cst, '0');
expectLocation(cst, '0.markup');
expectLocation(cst, '0.markup.expression');
});
});
});

describe('Case: LiquidNode', () => {
Expand Down
17 changes: 16 additions & 1 deletion src/parser/cst.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export enum ConcreteNodeTypes {

LiquidVariable = 'LiquidVariable',
String = 'String',
Number = 'Number',
}

export interface Parsers {
Expand Down Expand Up @@ -146,14 +147,21 @@ export interface ConcreteLiquidVariable
export type ConcreteLiquidFilters = undefined; // TODO

// TODO
export type ConcreteLiquidExpression = ConcreteStringLiteral;
export type ConcreteLiquidExpression =
| ConcreteStringLiteral
| ConcreteNumberLiteral;

export interface ConcreteStringLiteral
extends ConcreteBasicNode<ConcreteNodeTypes.String> {
value: string;
single: boolean;
}

export interface ConcreteNumberLiteral
extends ConcreteBasicNode<ConcreteNodeTypes.Number> {
value: string; // float parsing is weird but supported
}

export type ConcreteHtmlNode =
| ConcreteHtmlComment
| ConcreteHtmlRawTag
Expand Down Expand Up @@ -365,6 +373,13 @@ export function toLiquidHtmlCST(text: string): LiquidHtmlCST {
locEnd,
},

liquidNumber: {
type: ConcreteNodeTypes.Number,
value: 0,
locStart,
locEnd,
},

liquidInlineComment: {
type: ConcreteNodeTypes.LiquidTag,
name: 3,
Expand Down
2 changes: 2 additions & 0 deletions src/printer/preprocess/augment-with-css-properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ function getCssDisplay(

case NodeTypes.LiquidVariable:
case NodeTypes.String:
case NodeTypes.Number:
return 'should not be relevant';

default:
Expand Down Expand Up @@ -128,6 +129,7 @@ function getNodeCssStyleWhiteSpace(node: AugmentedNode<WithSiblings>): string {

case NodeTypes.LiquidVariable:
case NodeTypes.String:
case NodeTypes.Number:
return 'should not be relevant';

default:
Expand Down
4 changes: 4 additions & 0 deletions src/printer/printer-liquid-html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,10 @@ function printNode(
return [quote, node.value, quote];
}

case NodeTypes.Number: {
return node.value;
}

case NodeTypes.LiquidVariable: {
// TODO this is where you'll do the pipe first/last logic.
return [path.call(print, 'expression')];
Expand Down
4 changes: 2 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ export enum NodeTypes {
TextNode = 'TextNode',

LiquidVariable = 'LiquidVariable',
VariableLookup = 'VariableLookup',
String = 'String',
Number = 'Number',
Range = 'Range',
// Range = 'Range',
// VariableLookup = 'VariableLookup',
}

export const HtmlNodeTypes = [
Expand Down
13 changes: 13 additions & 0 deletions test/liquid-drop-number/fixed.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
It should parse and print as numbers
{{ -1 }}
{{ -0 }}
{{ 0 }}
{{ 1 }}
{{ -1.0 }}
{{ -0.0 }}
{{ 0.0 }}
{{ 1.0 }}

It should keep weird ass multi dots
{{- 1.0.0 -}}
{{- -1.0.0 -}}
13 changes: 13 additions & 0 deletions test/liquid-drop-number/index.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
It should parse and print as numbers
{{ -1}}
{{ -0}}
{{0}}
{{1}}
{{ -1.0}}
{{ -0.0}}
{{0.0}}
{{1.0}}

It should keep weird ass multi dots
{{- 1.0.0 -}}
{{- -1.0.0 -}}
6 changes: 6 additions & 0 deletions test/liquid-drop-number/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { assertFormattedEqualsFixed } from '../test-helpers';
import * as path from 'path';

describe(`Unit: ${path.basename(__dirname)}`, () => {
assertFormattedEqualsFixed(__dirname);
});

0 comments on commit 96f2b11

Please sign in to comment.