@xaendar/compiler 0.0.4 → 0.1.0

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.
Files changed (39) hide show
  1. package/package.json +19 -11
  2. package/xaendar-compiler.es.d.ts +199 -0
  3. package/xaendar-compiler.es.js +505 -0
  4. package/xaendar-compiler.es.js.map +1 -0
  5. package/src/costants/chars.constants.ts +0 -188
  6. package/src/costants/tags/base-tags.constants.ts +0 -106
  7. package/src/costants/tags/not-alllowed-tags.constants.ts +0 -13
  8. package/src/costants/tags/not-allowed-chars.constants.ts +0 -24
  9. package/src/lexer/lexer.ts +0 -91
  10. package/src/lexer/models/current-char.type.ts +0 -17
  11. package/src/lexer/models/current-position.type.ts +0 -13
  12. package/src/lexer/models/lexer-cursor.model.ts +0 -192
  13. package/src/lexer/models/lexer-state.enum.ts +0 -13
  14. package/src/lexer/models/token-type.enum.ts +0 -17
  15. package/src/lexer/models/token.type.ts +0 -62
  16. package/src/lexer/models/transition-function/transition-function-context.type.ts +0 -27
  17. package/src/lexer/models/transition-function/transition-function-return-type.type.ts +0 -48
  18. package/src/lexer/models/transition-function/transition-function.type.ts +0 -36
  19. package/src/lexer/states/attribute.state.ts +0 -47
  20. package/src/lexer/states/event.state.ts +0 -38
  21. package/src/lexer/states/interpolation-expression.state.ts +0 -68
  22. package/src/lexer/states/interpolation-literal.state.ts +0 -71
  23. package/src/lexer/states/interpolation.state.ts +0 -31
  24. package/src/lexer/states/tag-body.state.ts +0 -43
  25. package/src/lexer/states/tag-close.state.ts +0 -46
  26. package/src/lexer/states/tag-open-end.state.ts +0 -40
  27. package/src/lexer/states/tag-open-name.state.ts +0 -50
  28. package/src/lexer/states/text.state.ts +0 -61
  29. package/src/parser/models/ast.type.ts +0 -34
  30. package/src/parser/models/current-token.type.ts +0 -6
  31. package/src/parser/models/node.enum.ts +0 -5
  32. package/src/parser/models/parser-cursor.model.ts +0 -133
  33. package/src/parser/parser.ts +0 -225
  34. package/src/public-api.ts +0 -3
  35. package/src/render-generator/render-generator.model.ts +0 -73
  36. package/src/utils/chars.utils.ts +0 -70
  37. package/src/utils/tags.utils.ts +0 -36
  38. package/tsconfig.json +0 -3
  39. package/vite.config.ts +0 -4
@@ -1,62 +0,0 @@
1
- import { TokenType } from './token-type.enum';
2
-
3
- export type Token =
4
- | TagOpenNameToken
5
- | TagSelfCloseToken
6
- | TagCloseToken
7
- | TagCloseNameToken
8
- | AttributeToken
9
- | EventToken
10
- | TextToken
11
- | InterpolationExpressionToken
12
- | InterpolationLiteralToken
13
- | EOFToken
14
-
15
- export type TagOpenNameToken = {
16
- type: TokenType.TAG_OPEN_NAME;
17
- parts: [string];
18
- }
19
-
20
- export type EventToken = {
21
- type: TokenType.EVENT
22
- parts: [string]
23
- }
24
-
25
- export type AttributeToken = {
26
- type: TokenType.ATTRIBUTE
27
- parts: [string]
28
- }
29
-
30
- export type TextToken = {
31
- type: TokenType.TEXT,
32
- parts: [string]
33
- }
34
-
35
- export type InterpolationExpressionToken = {
36
- type: TokenType.INTERPOLATION_EXPRESSION;
37
- parts: [string];
38
- }
39
-
40
- export type InterpolationLiteralToken = {
41
- type: TokenType.INTERPOLATION_LITERAL;
42
- parts: [string];
43
- }
44
-
45
- export type TagSelfCloseToken = {
46
- type: TokenType.TAG_SELF_CLOSE,
47
- parts: []
48
- }
49
-
50
- export type TagCloseNameToken = {
51
- type: TokenType.TAG_CLOSE_NAME,
52
- parts: [string]
53
- }
54
-
55
- export type TagCloseToken = {
56
- type: TokenType.TAG_OPEN_END,
57
- parts: []
58
- }
59
-
60
- export type EOFToken = {
61
- type: TokenType.EOF
62
- }
@@ -1,27 +0,0 @@
1
- import { LexerState } from '../lexer-state.enum'
2
-
3
- /**
4
- * Context object passed by the Lexer engine to each
5
- * lexer transition function.
6
- *
7
- * This context exposes read-only information about the
8
- * internal execution state of the lexer, without allowing
9
- * direct mutation of the engine.
10
- */
11
- export type LexerTransitionFunctionContext = {
12
- /**
13
- * Read-only view of the lexer state stack.
14
- *
15
- * The stack represents the execution history of the lexer
16
- * and is used to support nested or temporary states
17
- * (e.g. interpolations, embedded expressions, attribute values).
18
- *
19
- * Conceptually, the lexer behaves as a Pushdown Automaton (PDA),
20
- * where this stack allows the engine to return to a previous
21
- * state after completing a nested transition.
22
- *
23
- * The array is ordered from bottom (oldest state)
24
- * to top (most recent state).
25
- */
26
- history: Array<LexerState>
27
- }
@@ -1,48 +0,0 @@
1
- import { LexerState } from '../lexer-state.enum'
2
- import { Token } from '../token.type'
3
-
4
- /**
5
- * Result returned by a lexer state transition function.
6
- *
7
- * Each lexer state is implemented as a pure function that:
8
- * - consumes characters from the cursor
9
- * - optionally emits tokens
10
- * - decides the next lexer state
11
- * - optionally manipulates the lexer state stack
12
- */
13
- export type LexerTransitionFunctionReturnType = {
14
-
15
- /**
16
- * The next state the lexer should transition to.
17
- *
18
- * This is always required and represents the logical continuation
19
- * of the lexing process after the current state has finished consuming input.
20
- */
21
- state: LexerState
22
- /**
23
- * Tokens produced while consuming input in the current state.
24
- *
25
- * This field is optional because some state transitions
26
- * may only advance the cursor or change state without
27
- * emitting any tokens.
28
- */
29
- tokens?: Token[]
30
- /**
31
- * Whether the lexer should pop the previous state from the state stack
32
- * after this transition.
33
- *
34
- * This is typically used for temporary or nested states
35
- * such as interpolations, where the lexer needs to return
36
- * to the state it was in before entering the nested context.
37
- */
38
- popState?: boolean
39
- /**
40
- * Whether the lexer should push the current state onto the state stack
41
- * before transitioning to the next state.
42
- *
43
- * This is useful when entering a nested or contextual state
44
- * (e.g. interpolations or embedded expressions) where the lexer
45
- * must remember where it came from in order to resume correctly.
46
- */
47
- pushState?: boolean
48
- }
@@ -1,36 +0,0 @@
1
- import { LexerCursor } from '../lexer-cursor.model';
2
- import { LexerTransitionFunctionContext } from './transition-function-context.type';
3
- import { LexerTransitionFunctionReturnType } from './transition-function-return-type.type';
4
-
5
- /**
6
- * A lexer transition function.
7
- *
8
- * A transition function is responsible for:
9
- * - Reading characters from the input stream via the {@link LexerCursor}
10
- * - Emitting zero or more tokens
11
- * - Deciding the next lexer state
12
- *
13
- * Transition functions must be **pure with respect to the lexer engine**:
14
- * they must not mutate the engine state directly, but instead communicate
15
- * their intent through the returned {@link LexerTransitionFunctionReturnType}.
16
- *
17
- * The lexer engine executes transition functions as part of a
18
- * Pushdown Automaton (PDA), allowing nested states such as interpolations
19
- * or embedded expressions.
20
- *
21
- * @param cursor
22
- * Cursor used to inspect and consume characters from the input stream.
23
- * The cursor encapsulates all low-level navigation logic (peek, advance,
24
- * position tracking, EOF handling).
25
- *
26
- * @param context
27
- * Read-only contextual information provided by the lexer engine,
28
- * including the current state stack and execution history.
29
- *
30
- * @returns
31
- * An object describing the outcome of the transition:
32
- * - the next lexer state
33
- * - any emitted tokens
34
- * - optional stack operations (push / pop)
35
- */
36
- export type LexerTransitionFunction = (cursor: LexerCursor, context: LexerTransitionFunctionContext) => LexerTransitionFunctionReturnType;
@@ -1,47 +0,0 @@
1
- import { GREATER_THEN, LEFT_BRACE, SLASH, SPACE } from '../../costants/chars.constants';
2
- import { LexerCursor } from '../models/lexer-cursor.model';
3
- import { LexerState } from '../models/lexer-state.enum';
4
- import { TokenType } from '../models/token-type.enum';
5
- import { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';
6
- import { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';
7
-
8
- export function consumeAttribute(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {
9
- let read = true;
10
- let attribute = '';
11
- let retVal!: LexerTransitionFunctionReturnType;
12
-
13
- while (read) {
14
- switch (cursor.peek()) {
15
- case SPACE:
16
- case SLASH:
17
- case GREATER_THEN:
18
- retVal = {
19
- state: LexerState.TAG_BODY,
20
- tokens: [{
21
- type: TokenType.ATTRIBUTE,
22
- parts: [attribute]
23
- }]
24
- };
25
- read = false;
26
- break;
27
-
28
- case LEFT_BRACE:
29
- retVal = {
30
- state: LexerState.INTERPOLATION,
31
- tokens: [{
32
- type: TokenType.ATTRIBUTE,
33
- parts: [attribute]
34
- }],
35
- pushState: true
36
- };
37
- read = false;
38
- break;
39
-
40
- default:
41
- cursor.advance();
42
- attribute = `${attribute}${cursor.currentChar.value}`
43
- }
44
- }
45
-
46
- return retVal;
47
- }
@@ -1,38 +0,0 @@
1
- import { GREATER_THEN, SLASH, SPACE } from '../../costants/chars.constants';
2
- import { LexerCursor } from '../models/lexer-cursor.model';
3
- import { LexerState } from '../models/lexer-state.enum';
4
- import { TokenType } from '../models/token-type.enum';
5
- import { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';
6
- import { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';
7
-
8
- export function consumeEvent(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {
9
- let read = true;
10
- let event = '';
11
- let retVal!: LexerTransitionFunctionReturnType;
12
-
13
- // Consume '@' character
14
- cursor.advance();
15
-
16
- while (read) {
17
- switch (cursor.peek()) {
18
- case SPACE:
19
- case SLASH:
20
- case GREATER_THEN:
21
- retVal = {
22
- state: LexerState.TAG_BODY,
23
- tokens: [{
24
- type: TokenType.EVENT,
25
- parts: [event]
26
- }]
27
- };
28
- read = false;
29
- break;
30
-
31
- default:
32
- cursor.advance();
33
- event = `${event}${cursor.currentChar.value}`
34
- }
35
- }
36
-
37
- return retVal;
38
- }
@@ -1,68 +0,0 @@
1
- import { LEFT_BRACE, RIGHT_BRACE, SPACE } from '../../costants/chars.constants';
2
- import { LexerCursor } from '../models/lexer-cursor.model';
3
- import { LexerState } from '../models/lexer-state.enum';
4
- import { TokenType } from '../models/token-type.enum';
5
- import { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';
6
- import { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';
7
-
8
- export function consumeInterpolationExpression(cursor: LexerCursor, context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {
9
- let read = true;
10
- let interpolation = '';
11
- let deep = 1
12
- let retVal!: LexerTransitionFunctionReturnType;
13
-
14
- while (read) {
15
- switch (cursor.peek()) {
16
- case LEFT_BRACE:
17
- deep++;
18
- interpolation = addCharacter(cursor, interpolation);
19
- break;
20
-
21
- case RIGHT_BRACE:
22
- deep--;
23
-
24
- if (deep === 0) {
25
- cursor.advance();
26
- /*
27
- After an interpolation we have to understanad where to transite
28
- The next state depends from the previous state
29
- */
30
- const previousState = context.history.pop();
31
- let state!: LexerState;
32
-
33
- switch (previousState) {
34
- case LexerState.ATTRIBUTE:
35
- state = LexerState.TAG_BODY
36
- break;
37
-
38
- case LexerState.TEXT:
39
- state = LexerState.TEXT
40
- };
41
-
42
- retVal = {
43
- state,
44
- tokens: [{
45
- type: TokenType.INTERPOLATION_EXPRESSION,
46
- parts: [interpolation]
47
- }],
48
- popState: true
49
- }
50
- read = false;
51
- } else {
52
- interpolation = addCharacter(cursor, interpolation);
53
- }
54
-
55
- break;
56
-
57
- default:
58
- interpolation = addCharacter(cursor, interpolation);
59
- }
60
- }
61
-
62
- return retVal;
63
- }
64
-
65
- function addCharacter(cursor: LexerCursor, interpolation: string): string {
66
- cursor.advance(1);
67
- return `${interpolation}${cursor.currentChar.value}`;
68
- }
@@ -1,71 +0,0 @@
1
- import { GRAVE_ACCENT, RIGHT_BRACE } from '../../costants/chars.constants';
2
- import { LexerCursor } from '../models/lexer-cursor.model';
3
- import { LexerState } from '../models/lexer-state.enum';
4
- import { TokenType } from '../models/token-type.enum';
5
- import { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';
6
- import { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';
7
-
8
- export function consumeInterpolationliteral(cursor: LexerCursor, context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {
9
- let read = true;
10
- let interpolation = '';
11
- let retVal!: LexerTransitionFunctionReturnType;
12
-
13
- // Consume '`' character
14
- cursor.advance();
15
-
16
- while (read) {
17
- switch (cursor.peek()) {
18
- case GRAVE_ACCENT:
19
- cursor.advance();
20
-
21
- if (cursor.peek() === RIGHT_BRACE) {
22
- cursor.advance();
23
- /*
24
- After an interpolation we have to understanad where to transite
25
- The next state depends from the previous state
26
- */
27
- const previousState = context.history.pop();
28
- let state!: LexerState;
29
-
30
- switch (previousState) {
31
- case LexerState.ATTRIBUTE:
32
- state = LexerState.TAG_BODY
33
- break;
34
-
35
- case LexerState.TEXT:
36
- state = LexerState.TEXT
37
- };
38
-
39
- retVal = {
40
- state,
41
- tokens: [{
42
- type: TokenType.INTERPOLATION_LITERAL,
43
- parts: [interpolation]
44
- }],
45
- popState: true
46
- }
47
- read = false;
48
- } else {
49
- /*
50
- If ` is not followed by }, it means the interpolation is not closed
51
- and ` is part of the interpolated string
52
- |
53
- ˅
54
- Example: {`text ${var} ` text`}
55
- */
56
- interpolation = `${interpolation}${cursor.currentChar.value}`
57
- }
58
- break;
59
-
60
- default:
61
- interpolation = addCharacter(cursor, interpolation);
62
- }
63
- }
64
-
65
- return retVal;
66
- }
67
-
68
- function addCharacter(cursor: LexerCursor, interpolation: string): string {
69
- cursor.advance(1);
70
- return `${interpolation}${cursor.currentChar.value}`;
71
- }
@@ -1,31 +0,0 @@
1
- import { GRAVE_ACCENT, SPACE } from '../../costants/chars.constants';
2
- import { isJSIdentifierStart } from '../../utils/chars.utils';
3
- import { LexerCursor } from '../models/lexer-cursor.model';
4
- import { LexerState } from '../models/lexer-state.enum';
5
- import { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';
6
- import { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';
7
-
8
- export function consumeInterpolation(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {
9
- let retVal!: LexerTransitionFunctionReturnType;
10
-
11
- // Consume '{' characters
12
- cursor.advance();
13
-
14
- /*
15
- Skip all the spaces between '{' and the actual interpolation content
16
- Ex: '{ label}
17
- */
18
- cursor.skipSpaces();
19
-
20
- const nextChar = cursor.peek();
21
-
22
- if (nextChar === GRAVE_ACCENT) {
23
- retVal = { state: LexerState.INTERPOLATION_LITERAL };
24
- } else if (isJSIdentifierStart(nextChar)) {
25
- retVal = { state: LexerState.INTERPOLATION_EXPRESSION };
26
- } else {
27
- throw new Error(`Unrecognized First Character ${String.fromCharCode(nextChar)} in interpolation`);
28
- }
29
-
30
- return retVal;
31
- }
@@ -1,43 +0,0 @@
1
- import { AT_SIGN, GREATER_THEN, SLASH, SPACE } from '../../costants/chars.constants';
2
- import { LexerCursor } from '../models/lexer-cursor.model';
3
- import { LexerState } from '../models/lexer-state.enum';
4
- import { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';
5
- import { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';
6
-
7
- export function consumeTagBody(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {
8
- let read = true;
9
- let retVal!: LexerTransitionFunctionReturnType;
10
-
11
- while (read) {
12
- const nextChar = cursor.peek();
13
-
14
- switch (nextChar) {
15
- case AT_SIGN:
16
- retVal = {
17
- state: LexerState.EVENT
18
- }
19
- read = false;
20
- break;
21
-
22
- case SPACE:
23
- cursor.advance();
24
- break;
25
-
26
- case GREATER_THEN:
27
- case SLASH:
28
- retVal = {
29
- state: LexerState.TAG_OPEN_END
30
- }
31
- read = false;
32
- break;
33
-
34
- default:
35
- retVal = {
36
- state: LexerState.ATTRIBUTE
37
- }
38
- read = false;
39
- }
40
- }
41
-
42
- return retVal
43
- }
@@ -1,46 +0,0 @@
1
- import { GREATER_THEN, SPACE } from '../../costants/chars.constants';
2
- import { LexerCursor } from '../models/lexer-cursor.model';
3
- import { LexerState } from '../models/lexer-state.enum';
4
- import { TokenType } from '../models/token-type.enum';
5
- import { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';
6
- import { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';
7
-
8
- export function consumeTagClose(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {
9
- let read = true;
10
- let tagName = '';
11
- let retVal!: LexerTransitionFunctionReturnType;
12
-
13
- // Skip '</'
14
- cursor.advance(2);
15
-
16
- /*
17
- Skip all the spaces between '</' and the actual tag name
18
- Ex: '</ div>
19
- */
20
- cursor.skipSpaces();
21
-
22
- while (read) {
23
- switch (cursor.peek()) {
24
- case GREATER_THEN:
25
- cursor.advance();
26
- retVal = {
27
- state: LexerState.TEXT,
28
- tokens: [{
29
- type: TokenType.TAG_CLOSE_NAME,
30
- parts: [tagName]
31
- }]
32
- };
33
- read = false;
34
- break;
35
-
36
- case SPACE:
37
- throw new Error('Tag Close Name cannot contains spaces');
38
-
39
- default:
40
- cursor.advance();
41
- tagName = `${tagName}${cursor.currentChar.value}`;
42
- }
43
- }
44
-
45
- return retVal;
46
- }
@@ -1,40 +0,0 @@
1
- import { GREATER_THEN } from '../../costants/chars.constants';
2
- import { LexerCursor } from '../models/lexer-cursor.model';
3
- import { LexerState } from '../models/lexer-state.enum';
4
- import { TokenType } from '../models/token-type.enum';
5
- import { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';
6
- import { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';
7
-
8
- export function consumeTagOpenEnd(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {
9
- let retVal!: LexerTransitionFunctionReturnType
10
-
11
- // We arrive in this point by reading '>' or '/' at the end of a Open Tag
12
- if (cursor.peek() === GREATER_THEN) {
13
- cursor.advance();
14
- retVal = {
15
- state: LexerState.TEXT,
16
- tokens: [{
17
- type: TokenType.TAG_OPEN_END,
18
- parts: []
19
- }]
20
- };
21
- } else {
22
- cursor.advance();
23
- const nextChar = cursor.peek();
24
-
25
- if (nextChar === GREATER_THEN) {
26
- cursor.advance();
27
- retVal = {
28
- state: LexerState.TEXT,
29
- tokens: [{
30
- type: TokenType.TAG_SELF_CLOSE,
31
- parts: []
32
- }]
33
- };
34
- } else {
35
- throw new Error(`Unexpected character ${nextChar} for closing tag.\nExpected />\nRead of /${String.fromCharCode(nextChar)}\nAt line ${cursor.position.row + 1} col ${cursor.position.column + 1}`)
36
- }
37
- }
38
-
39
- return retVal
40
- }
@@ -1,50 +0,0 @@
1
- import { GREATER_THEN, SLASH, SPACE } from '../../costants/chars.constants';
2
- import { LexerCursor } from '../models/lexer-cursor.model';
3
- import { LexerState } from '../models/lexer-state.enum';
4
- import { TokenType } from '../models/token-type.enum';
5
- import { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';
6
- import { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';
7
-
8
- export function consumeTagOpenName(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {
9
- let read = true;
10
- let tagName = '';
11
- let retVal!: LexerTransitionFunctionReturnType
12
-
13
- // Consume '<' character
14
- cursor.advance();
15
-
16
- /*
17
- Skip all the spaces between '<' and the actual tag name
18
- Ex: '< div>
19
- */
20
- cursor.skipSpaces();
21
-
22
- /*
23
- Keep read input until:
24
- - Space: <span
25
- - GT: <span>
26
- - Slash (Self Closing tag) <span / or <span/
27
- */
28
- while (read) {
29
- switch (cursor.peek()) {
30
- case SPACE:
31
- case SLASH:
32
- case GREATER_THEN:
33
- retVal = {
34
- state: LexerState.TAG_BODY,
35
- tokens: [{
36
- type: TokenType.TAG_OPEN_NAME,
37
- parts: [tagName]
38
- }]
39
- }
40
- read = false;
41
- break;
42
-
43
- default:
44
- cursor.advance();
45
- tagName = `${tagName}${cursor.currentChar.value}`
46
- }
47
- }
48
-
49
- return retVal
50
- }
@@ -1,61 +0,0 @@
1
- import { CR, LEFT_BRACE, LESS_THAN, LF, SLASH, SPACE } from '../../costants/chars.constants';
2
- import { isNotBlank } from '../../utils/chars.utils';
3
- import { LexerCursor } from '../models/lexer-cursor.model';
4
- import { LexerState } from '../models/lexer-state.enum';
5
- import { TokenType } from '../models/token-type.enum';
6
- import { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';
7
- import { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';
8
-
9
- export function consumeText(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {
10
- let read = true;
11
- let text = '';
12
- let retVal!: LexerTransitionFunctionReturnType
13
-
14
- while (read) {
15
- switch (cursor.peek()) {
16
- case LESS_THAN:
17
- // If after '<' we read a '/', we suppose we're approaching a ClosureTag, otherwise an OpenTag
18
- const nextState = cursor.peek(1, { offset: 1 }) === SLASH ? LexerState.TAG_CLOSE : LexerState.TAG_OPEN_NAME;
19
- retVal = { state: nextState }
20
- read = false;
21
- break;
22
-
23
- case LEFT_BRACE:
24
- retVal = {
25
- state: LexerState.INTERPOLATION,
26
- pushState: true
27
- };
28
- read = false;
29
- break;
30
-
31
- case SPACE:
32
- case LF:
33
- case CR:
34
- cursor.advance();
35
- break;
36
-
37
- default:
38
- cursor.advance();
39
- text = `${text}${cursor.currentChar.value}`;
40
- }
41
- }
42
-
43
-
44
- /*
45
- If the first read character trigger a StateChange
46
- The cumulative `text` variable will be empty
47
-
48
- In this case we must NOT add any token
49
-
50
- Ex:
51
- Template starts with a tag:
52
- `<div ...`
53
- Or an interpolation:
54
- `{ myVariable }`
55
- */
56
- retVal.tokens = isNotBlank(text)
57
- ? [{ type: TokenType.TEXT, parts: [text] }]
58
- : undefined;
59
-
60
- return retVal
61
- }