Skip to content

Commit

Permalink
Update static TagNode.create to ingest setStart() logic
Browse files Browse the repository at this point in the history
improve readability of end pos offset for no attr tags
  • Loading branch information
Alteras1 committed Jul 31, 2024
1 parent da2f325 commit 3af485a
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 28 deletions.
4 changes: 3 additions & 1 deletion packages/bbob-parser/src/lexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const TAG_STATE_VALUE = 2;

const WHITESPACES = [SPACE, TAB];
const SPECIAL_CHARS = [EQ, SPACE, TAB];
const END_POS_OFFSET = 2; // length + start position offset

const isWhiteSpace = (char: string) => (WHITESPACES.indexOf(char) >= 0);
const isEscapeChar = (char: string) => char === BACKSLASH;
Expand Down Expand Up @@ -218,10 +219,11 @@ export function createLexer(buffer: string, options: LexerOptions = {}): LexerTo
if (isNoAttrsInTag || isClosingTag) {
const startPos = chars.getPos() - 1;
const name = chars.grabWhile((char) => char !== closeTag);
const endPos = startPos + name.length + END_POS_OFFSET;

chars.skip(); // skip closeTag

emitToken(TYPE_TAG, name, startPos, startPos + name.length + 2);
emitToken(TYPE_TAG, name, startPos, endPos);
checkContextFreeMode(name, isClosingTag);

return STATE_WORD;
Expand Down
5 changes: 2 additions & 3 deletions packages/bbob-parser/src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,7 @@ function parse(input: string, opts: ParseOptions = {}) {
function handleTagStart(token: Token) {
flushTagNodes();

const tagNode = TagNode.create(token.getValue(), {}, []);
tagNode.setStart(token.getStart(), token.getEnd());
const tagNode = TagNode.create(token.getValue(), {}, [], { from: token.getStart(), to: token.getEnd() });
const isNested = isTokenNested(token);

tagNodes.push(tagNode);
Expand All @@ -206,7 +205,7 @@ function parse(input: string, opts: ParseOptions = {}) {
function handleTagEnd(token: Token) {
const lastTagNode = nestedNodes.last();
if (isTagNode(lastTagNode)) {
lastTagNode.setEnd(token.getStart(), token.getEnd());
lastTagNode.setEnd({ from: token.getStart(), to: token.getEnd() });
}
flushTagNodes();

Expand Down
26 changes: 15 additions & 11 deletions packages/bbob-plugin-helper/src/TagNode.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { NodeContent, TagNodeObject, TagNodeTree } from "@bbob/types";
import type { NodeContent, TagNodeObject, TagNodeTree, TagPosition } from "@bbob/types";

import { OPEN_BRAKET, CLOSE_BRAKET, SLASH } from './char';
import {
Expand Down Expand Up @@ -57,8 +57,8 @@ export class TagNode<TagValue extends any = any> implements TagNodeObject {
public readonly tag: string | TagValue;
public attrs: Record<string, unknown>;
public content: TagNodeTree;
public start?: { from: number; to: number; };
public end?: { from: number; to: number; };
public start?: TagPosition;
public end?: TagPosition;

constructor(tag: string | TagValue, attrs: Record<string, unknown>, content: TagNodeTree) {
this.tag = tag;
Expand All @@ -78,12 +78,12 @@ export class TagNode<TagValue extends any = any> implements TagNodeObject {
return appendToNode(this, value);
}

setStart(from: number, to: number) {
this.start = { from, to };
setStart(value: TagPosition) {
this.start = value;
}

setEnd(from: number, to: number) {
this.end = { from, to };
setEnd(value: TagPosition) {
this.end = value;
}

get length(): number {
Expand All @@ -103,10 +103,10 @@ export class TagNode<TagValue extends any = any> implements TagNodeObject {
toTagNode() {
const newNode = new TagNode(String(this.tag).toLowerCase(), this.attrs, this.content);
if (this.start) {
newNode.setStart(this.start.from, this.start.to);
newNode.setStart(this.start);
}
if (this.end) {
newNode.setEnd(this.end.from, this.end.to);
newNode.setEnd(this.end);
}
return newNode;
}
Expand All @@ -122,8 +122,12 @@ export class TagNode<TagValue extends any = any> implements TagNodeObject {
return `${tagStart}${content}${this.toTagEnd({ openTag, closeTag })}`;
}

static create(tag: string, attrs: Record<string, unknown> = {}, content: TagNodeTree = null) {
return new TagNode(tag, attrs, content);
static create(tag: string, attrs: Record<string, unknown> = {}, content: TagNodeTree = null, start?: TagPosition) {
const node = new TagNode(tag, attrs, content);
if (start) {
node.setStart(start);
}
return node;
}

static isOf(node: TagNode, type: string) {
Expand Down
21 changes: 19 additions & 2 deletions packages/bbob-plugin-helper/test/TagNode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { TagNode } from '../src'

describe('@bbob/plugin-helper/TagNode', () => {
test('create', () => {
const tagNode = TagNode.create('test', {test: 1}, ['Hello']);
const tagNode = TagNode.create('test', {test: 1}, ['Hello'], {from: 0, to: 10});

expect(tagNode).toBeInstanceOf(TagNode)
});
Expand Down Expand Up @@ -36,12 +36,15 @@ describe('@bbob/plugin-helper/TagNode', () => {
});

test('toTagNode', () => {
const tagNode = TagNode.create('test', {test: 1}, ['Hello']);
const tagNode = TagNode.create('test', {test: 1}, ['Hello'], {from: 0, to: 10});
tagNode.setEnd({from: 20, to: 27});
const newTagNode = tagNode.toTagNode()

expect(newTagNode !== tagNode).toBe(true);
expect(newTagNode.tag).toEqual(tagNode.tag);
expect(newTagNode.content).toEqual(tagNode.content);
expect(newTagNode.start).toEqual(tagNode.start);
expect(newTagNode.end).toEqual(tagNode.end);
});

test('null content', () => {
Expand All @@ -56,6 +59,20 @@ describe('@bbob/plugin-helper/TagNode', () => {
expect(String(tagNode)).toBe('[img]');
});

test('setStart', () => {
const tagNode = TagNode.create('test', {test: 1}, ['Hello']);
tagNode.setStart({from: 0, to: 10});

expect(tagNode.start).toEqual({from: 0, to: 10});
});

test('setEnd', () => {
const tagNode = TagNode.create('test', {test: 1}, ['Hello']);
tagNode.setEnd({from: 20, to: 27});

expect(tagNode.end).toEqual({from: 20, to: 27});
});

describe('toString', () => {
test('tag with content and params', () => {
const tagNode = TagNode.create('test', {test: 1}, ['Hello']);
Expand Down
6 changes: 4 additions & 2 deletions packages/bbob-types/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ export interface TagNodeObject<TagValue extends any = any> {
readonly tag: TagValue;
attrs?: Record<string, unknown>;
content?: TagNodeTree<TagValue>;
start?: { from: number; to: number; };
end?: { from: number; to: number; };
start?: TagPosition;
end?: TagPosition;
}

export type NodeContent<TagValue extends any = any> = TagNodeObject<TagValue> | StringNode | null;

export type PartialNodeContent<TagValue extends any = any> = Partial<TagNodeObject<TagValue>> | StringNode | null;

export type TagNodeTree<TagValue extends any = any> = NodeContent<TagValue> | NodeContent<TagValue>[] | null;

export type TagPosition = { from: number; to: number; };
12 changes: 3 additions & 9 deletions packages/bbob-types/src/parser.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TagNodeTree } from "./common";
import { TagNodeTree, TagPosition } from "./common";

export interface ParseError {
tagName: string;
Expand All @@ -10,14 +10,8 @@ export interface TagNode {
readonly tag: string
attrs?: Record<string, unknown>
content?: TagNodeTree,
start?: {
from: number;
to: number;
};
end?: {
from: number;
to: number;
};
start?: TagPosition;
end?: TagPosition;
}

export interface Token<TokenValue = string> {
Expand Down

0 comments on commit 3af485a

Please sign in to comment.