@platformos/liquid-html-parser 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,62 @@
1
+ <h1 align="center" style="position: relative;" >
2
+ <br>
3
+ <img src="https://github.com/Platform-OS/platformos-tools/blob/main/packages/vscode-extension/images/platformos_logo.png?raw=true" alt="platformOS logo" width="200">
4
+ <br>
5
+ Liquid HTML parser
6
+ </h1>
7
+
8
+ <p align="center">
9
+ <a href="https://www.npmjs.com/package/@platformos/liquid-html-parser"><img src="https://img.shields.io/npm/v/@platformos/liquid-html-parser.svg?sanitize=true" alt="Version"></a>
10
+ <a href="https://github.com/Platform-OS/platformos-tools/blob/main/LICENSE.md"><img src="https://img.shields.io/npm/l/@platformos/liquid-html-parser.svg?sanitize=true" alt="License"></a>
11
+ <a href="https://github.com/Platform-OS/platformos-tools/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/Platform-OS/platformos-tools/actions/workflows/ci.yml/badge.svg"></a>
12
+ <!--
13
+ <a href="https://npmcharts.com/compare/@platformos/liquid-html-parser?minimal=true"><img src="https://img.shields.io/npm/dm/@platformos/prettier-plugin-liquid.svg?sanitize=true" alt="Downloads"></a>
14
+ -->
15
+ </p>
16
+
17
+ This module provides the Liquid HTML parser that powers the prettier plugin, linter and language server for platformOS.
18
+
19
+ It turns a `.liquid` file contents into an Abstract Syntax Tree (AST) that contains _both_ Liquid and HTML nodes.
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ # with npm
25
+ npm install @platformos/liquid-html-parser
26
+
27
+ # with yarn
28
+ yarn add @platformos/liquid-html-parser
29
+ ```
30
+
31
+ ## Usage
32
+
33
+ ```ts
34
+ import { toLiquidHtmlAST, LiquidHtmlNode, NodeTypes } from '@platformos/prettier-plugin-liquid';
35
+
36
+ const ast: LiquidHtmlNode = toLiquidHtmlAST(`
37
+ <body>
38
+ {% for product in all_products %}
39
+ <img src="{{ product | image_url }}">
40
+ {% endfor %}
41
+ </body>
42
+ `);
43
+ ```
44
+
45
+ ## You should know
46
+
47
+ Because Liquid is very permissive, things like the `name` of an HTML tag may have a surprising type: an array of `LiquidVariableOutput | TextNode`.
48
+
49
+ This is because the following use cases are supported by the parser:
50
+
51
+ ```liquid
52
+ {% # compound html tag names %}
53
+ <tag-{{ name }}>
54
+ </tag-{{ name }}>
55
+
56
+ {% # compound html attribute names %}
57
+ <img data-{{ attr_name }}="...">
58
+ ```
59
+
60
+ ## License
61
+
62
+ MIT.
@@ -0,0 +1,5 @@
1
+ export declare const getConditionalComment: (comment: string) => {
2
+ startTag: string;
3
+ body: string;
4
+ endTag: string;
5
+ } | undefined;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getConditionalComment = void 0;
4
+ const commentRegex = /(<!--\[if[^\]]*]>)((.|\n)*)(<!\[endif\]-->)$/;
5
+ const getConditionalComment = (comment) => {
6
+ const matches = comment.match(commentRegex);
7
+ if (matches) {
8
+ return {
9
+ startTag: matches[1],
10
+ body: matches[2].trim(),
11
+ endTag: matches[4],
12
+ };
13
+ }
14
+ };
15
+ exports.getConditionalComment = getConditionalComment;
16
+ //# sourceMappingURL=conditional-comment.js.map
@@ -0,0 +1,27 @@
1
+ import { MatchResult } from 'ohm-js';
2
+ import { NodeTypes, Position } from './types';
3
+ interface LineColPosition {
4
+ line: number;
5
+ column: number;
6
+ }
7
+ export declare class LiquidHTMLCSTParsingError extends SyntaxError {
8
+ loc?: {
9
+ start: LineColPosition;
10
+ end: LineColPosition;
11
+ };
12
+ constructor(ohm: MatchResult);
13
+ }
14
+ export type UnclosedNode = {
15
+ type: NodeTypes;
16
+ name: string;
17
+ blockStartPosition: Position;
18
+ };
19
+ export declare class LiquidHTMLASTParsingError extends SyntaxError {
20
+ loc?: {
21
+ start: LineColPosition;
22
+ end: LineColPosition;
23
+ };
24
+ unclosed: UnclosedNode | null;
25
+ constructor(message: string, source: string, startIndex: number, endIndex: number, unclosed?: UnclosedNode);
26
+ }
27
+ export {};
package/dist/errors.js ADDED
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.LiquidHTMLASTParsingError = exports.LiquidHTMLCSTParsingError = void 0;
7
+ const line_column_1 = __importDefault(require("line-column"));
8
+ class LiquidHTMLCSTParsingError extends SyntaxError {
9
+ constructor(ohm) {
10
+ super(ohm.shortMessage);
11
+ this.name = 'LiquidHTMLParsingError';
12
+ const input = ohm.input;
13
+ const errorPos = ohm._rightmostFailurePosition;
14
+ const lineCol = (0, line_column_1.default)(input).fromIndex(Math.min(errorPos, input.length - 1));
15
+ // Plugging ourselves into @babel/code-frame since this is how
16
+ // the babel parser can print where the parsing error occured.
17
+ // https://github.com/prettier/prettier/blob/cd4a57b113177c105a7ceb94e71f3a5a53535b81/src/main/parser.js
18
+ if (lineCol) {
19
+ this.loc = {
20
+ start: {
21
+ line: lineCol.line,
22
+ column: lineCol.col,
23
+ },
24
+ end: {
25
+ line: lineCol.line,
26
+ column: lineCol.col,
27
+ },
28
+ };
29
+ }
30
+ }
31
+ }
32
+ exports.LiquidHTMLCSTParsingError = LiquidHTMLCSTParsingError;
33
+ class LiquidHTMLASTParsingError extends SyntaxError {
34
+ constructor(message, source, startIndex, endIndex, unclosed) {
35
+ super(message);
36
+ this.name = 'LiquidHTMLParsingError';
37
+ this.unclosed = unclosed ?? null;
38
+ const lc = (0, line_column_1.default)(source);
39
+ const start = lc.fromIndex(startIndex);
40
+ const end = lc.fromIndex(Math.min(endIndex, source.length - 1));
41
+ // Plugging ourselves into @babel/code-frame since this is how
42
+ // the babel parser can print where the parsing error occured.
43
+ // https://github.com/prettier/prettier/blob/cd4a57b113177c105a7ceb94e71f3a5a53535b81/src/main/parser.js
44
+ this.loc = {
45
+ start: {
46
+ line: start.line,
47
+ column: start.col,
48
+ },
49
+ end: {
50
+ line: end.line,
51
+ column: end.col,
52
+ },
53
+ };
54
+ }
55
+ }
56
+ exports.LiquidHTMLASTParsingError = LiquidHTMLASTParsingError;
57
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1,16 @@
1
+ import { Grammar } from 'ohm-js';
2
+ export declare const liquidHtmlGrammars: import("ohm-js").Namespace;
3
+ export declare const TextNodeGrammar: Grammar;
4
+ export declare const LiquidDocGrammar: Grammar;
5
+ export interface LiquidGrammars {
6
+ Liquid: Grammar;
7
+ LiquidHTML: Grammar;
8
+ LiquidStatement: Grammar;
9
+ }
10
+ export declare const strictGrammars: LiquidGrammars;
11
+ export declare const tolerantGrammars: LiquidGrammars;
12
+ export declare const placeholderGrammars: LiquidGrammars;
13
+ export declare const BLOCKS: string[];
14
+ export declare const RAW_TAGS: string[];
15
+ export declare const VOID_ELEMENTS: string[];
16
+ export declare const TAGS_WITHOUT_MARKUP: string[];
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TAGS_WITHOUT_MARKUP = exports.VOID_ELEMENTS = exports.RAW_TAGS = exports.BLOCKS = exports.placeholderGrammars = exports.tolerantGrammars = exports.strictGrammars = exports.LiquidDocGrammar = exports.TextNodeGrammar = exports.liquidHtmlGrammars = void 0;
4
+ const ohm_js_1 = require("ohm-js");
5
+ exports.liquidHtmlGrammars = (0, ohm_js_1.grammars)(require('../grammar/liquid-html.ohm.js'));
6
+ exports.TextNodeGrammar = exports.liquidHtmlGrammars['Helpers'];
7
+ exports.LiquidDocGrammar = exports.liquidHtmlGrammars['LiquidDoc'];
8
+ exports.strictGrammars = {
9
+ Liquid: exports.liquidHtmlGrammars['StrictLiquid'],
10
+ LiquidHTML: exports.liquidHtmlGrammars['StrictLiquidHTML'],
11
+ LiquidStatement: exports.liquidHtmlGrammars['StrictLiquidStatement'],
12
+ };
13
+ exports.tolerantGrammars = {
14
+ Liquid: exports.liquidHtmlGrammars['Liquid'],
15
+ LiquidHTML: exports.liquidHtmlGrammars['LiquidHTML'],
16
+ LiquidStatement: exports.liquidHtmlGrammars['LiquidStatement'],
17
+ };
18
+ exports.placeholderGrammars = {
19
+ Liquid: exports.liquidHtmlGrammars['WithPlaceholderLiquid'],
20
+ LiquidHTML: exports.liquidHtmlGrammars['WithPlaceholderLiquidHTML'],
21
+ LiquidStatement: exports.liquidHtmlGrammars['WithPlaceholderLiquidStatement'],
22
+ };
23
+ // see ../../grammar/liquid-html.ohm for full list
24
+ exports.BLOCKS = exports.strictGrammars.LiquidHTML.rules.blockName.body.factors[0].terms.map((x) => x.obj);
25
+ // see ../../grammar/liquid-html.ohm for full list
26
+ exports.RAW_TAGS = exports.strictGrammars.LiquidHTML.rules.liquidRawTag.body.terms
27
+ .map((term) => term.args[0].obj)
28
+ .concat('comment');
29
+ // see ../../grammar/liquid-html.ohm for full list
30
+ exports.VOID_ELEMENTS = exports.strictGrammars.LiquidHTML.rules.voidElementName.body.factors[0].terms.map((x) => x.args[0].obj);
31
+ exports.TAGS_WITHOUT_MARKUP = [
32
+ 'style',
33
+ 'schema',
34
+ 'javascript',
35
+ 'else',
36
+ 'break',
37
+ 'continue',
38
+ 'comment',
39
+ 'raw',
40
+ 'doc',
41
+ ];
42
+ //# sourceMappingURL=grammar.js.map
@@ -0,0 +1,5 @@
1
+ export * from './stage-2-ast';
2
+ export * from './types';
3
+ export * from './errors';
4
+ export { TAGS_WITHOUT_MARKUP, RAW_TAGS, VOID_ELEMENTS, BLOCKS } from './grammar';
5
+ export { getConditionalComment } from './conditional-comment';
package/dist/index.js ADDED
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.getConditionalComment = exports.BLOCKS = exports.VOID_ELEMENTS = exports.RAW_TAGS = exports.TAGS_WITHOUT_MARKUP = void 0;
18
+ __exportStar(require("./stage-2-ast"), exports);
19
+ __exportStar(require("./types"), exports);
20
+ __exportStar(require("./errors"), exports);
21
+ var grammar_1 = require("./grammar");
22
+ Object.defineProperty(exports, "TAGS_WITHOUT_MARKUP", { enumerable: true, get: function () { return grammar_1.TAGS_WITHOUT_MARKUP; } });
23
+ Object.defineProperty(exports, "RAW_TAGS", { enumerable: true, get: function () { return grammar_1.RAW_TAGS; } });
24
+ Object.defineProperty(exports, "VOID_ELEMENTS", { enumerable: true, get: function () { return grammar_1.VOID_ELEMENTS; } });
25
+ Object.defineProperty(exports, "BLOCKS", { enumerable: true, get: function () { return grammar_1.BLOCKS; } });
26
+ var conditional_comment_1 = require("./conditional-comment");
27
+ Object.defineProperty(exports, "getConditionalComment", { enumerable: true, get: function () { return conditional_comment_1.getConditionalComment; } });
28
+ //# sourceMappingURL=index.js.map