Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@markuplint/parser-utils

Package Overview
Dependencies
Maintainers
1
Versions
139
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@markuplint/parser-utils - npm Package Compare versions

Comparing version 4.0.0-dev.10 to 4.0.0-dev.12

lib/enums.d.ts

20

lib/attr-tokenizer.d.ts
import type { QuoteSet } from './types.js';
import type { MLASTHTMLAttr } from '@markuplint/ml-ast';
import { AttrState } from './attr-parser.js';
export declare function attrTokenizer(raw: string, line: number, col: number, startOffset: number, quoteSet?: ReadonlyArray<QuoteSet>, startState?: AttrState, quoteInValueChars?: ReadonlyArray<QuoteSet>, spaces?: ReadonlyArray<string>): MLASTHTMLAttr & {
__leftover?: string;
import { AttrState } from './enums.js';
/**
* @see https://html.spec.whatwg.org/multipage/parsing.html#tag-name-state
* @see https://html.spec.whatwg.org/multipage/parsing.html#before-attribute-name-state
* @see https://html.spec.whatwg.org/multipage/parsing.html#attribute-name-state
*/
export declare function attrTokenizer(raw: string, quoteSet?: readonly QuoteSet[], startState?: AttrState, quoteInValueChars?: ReadonlyArray<QuoteSet>, endOfUnquotedValueChars?: ReadonlyArray<string>): {
spacesBeforeAttrName: string;
attrName: string;
spacesBeforeEqual: string;
equal: string;
spacesAfterEqual: string;
quoteStart: string;
attrValue: string;
quoteEnd: string;
leftover: string;
};

234

lib/attr-tokenizer.js

@@ -1,75 +0,169 @@

import { AttrState, attrParser } from './attr-parser.js';
import { tokenizer, uuid } from './create-token.js';
export function attrTokenizer(raw, line, col, startOffset, quoteSet, startState = AttrState.BeforeName, quoteInValueChars, spaces) {
const parsed = attrParser(raw, quoteSet, startState, quoteInValueChars, spaces);
let offset = startOffset;
const spacesBeforeName = tokenizer(parsed.spacesBeforeAttrName, line, col, offset);
line = spacesBeforeName.endLine;
col = spacesBeforeName.endCol;
offset = spacesBeforeName.endOffset;
const name = tokenizer(parsed.attrName, line, col, offset);
line = name.endLine;
col = name.endCol;
offset = name.endOffset;
const spacesBeforeEqual = tokenizer(parsed.spacesBeforeEqual, line, col, offset);
line = spacesBeforeEqual.endLine;
col = spacesBeforeEqual.endCol;
offset = spacesBeforeEqual.endOffset;
const equal = tokenizer(parsed.equal, line, col, offset);
line = equal.endLine;
col = equal.endCol;
offset = equal.endOffset;
const spacesAfterEqual = tokenizer(parsed.spacesAfterEqual, line, col, offset);
line = spacesAfterEqual.endLine;
col = spacesAfterEqual.endCol;
offset = spacesAfterEqual.endOffset;
const startQuote = tokenizer(parsed.quoteStart, line, col, offset);
line = startQuote.endLine;
col = startQuote.endCol;
offset = startQuote.endOffset;
const value = tokenizer(parsed.attrValue, line, col, offset);
line = value.endLine;
col = value.endCol;
offset = value.endOffset;
const endQuote = tokenizer(parsed.quoteEnd, line, col, offset);
const attrToken = tokenizer(parsed.attrName +
parsed.spacesBeforeEqual +
parsed.equal +
parsed.spacesAfterEqual +
parsed.quoteStart +
parsed.attrValue +
parsed.quoteEnd, name.startLine, name.startCol, name.startOffset);
const result = {
type: 'html-attr',
uuid: uuid(),
raw: attrToken.raw,
startOffset: attrToken.startOffset,
endOffset: attrToken.endOffset,
startLine: attrToken.startLine,
endLine: attrToken.endLine,
startCol: attrToken.startCol,
endCol: attrToken.endCol,
spacesBeforeName,
name,
import { defaultSpaces } from './const.js';
import { AttrState } from './enums.js';
const defaultQuoteSet = [
{ start: '"', end: '"' },
{ start: "'", end: "'" },
];
const defaultQuoteInValueChars = [];
const spaces = defaultSpaces;
const EQUAL = '=';
/**
* @see https://html.spec.whatwg.org/multipage/parsing.html#tag-name-state
* @see https://html.spec.whatwg.org/multipage/parsing.html#before-attribute-name-state
* @see https://html.spec.whatwg.org/multipage/parsing.html#attribute-name-state
*/
export function attrTokenizer(raw, quoteSet = defaultQuoteSet, startState = AttrState.BeforeName, quoteInValueChars = defaultQuoteInValueChars, endOfUnquotedValueChars = [...defaultSpaces, '/', '>']) {
let state = startState;
let spacesBeforeAttrName = '';
let attrName = '';
let spacesBeforeEqual = '';
let equal = '';
let spacesAfterEqual = '';
let quoteTypeIndex = -1;
let quoteStart = '';
let attrValue = '';
let quoteEnd = '';
const isBeforeValueStarted = startState === AttrState.BeforeValue;
const quoteModeStack = [];
const chars = [...raw];
while (chars.length > 0) {
if (state === AttrState.AfterValue) {
break;
}
const char = chars.shift();
switch (state) {
case AttrState.BeforeName: {
if (char === '>') {
chars.unshift(char);
state = AttrState.AfterValue;
break;
}
if (char === '/') {
chars.unshift(char);
state = AttrState.AfterValue;
break;
}
if (spaces.includes(char)) {
spacesBeforeAttrName += char;
break;
}
attrName += char;
state = AttrState.Name;
break;
}
case AttrState.Name: {
if (char === '>') {
chars.unshift(char);
state = AttrState.AfterValue;
break;
}
if (char === '/') {
chars.unshift(char);
state = AttrState.AfterValue;
break;
}
if (spaces.includes(char)) {
spacesBeforeEqual += char;
state = AttrState.Equal;
break;
}
if (char === EQUAL) {
equal += char;
state = AttrState.BeforeValue;
break;
}
attrName += char;
break;
}
case AttrState.Equal: {
if (spaces.includes(char)) {
spacesBeforeEqual += char;
break;
}
if (char === EQUAL) {
equal += char;
state = AttrState.BeforeValue;
break;
}
// End of attribute
chars.unshift(spacesBeforeEqual, char);
spacesBeforeEqual = '';
state = AttrState.AfterValue;
break;
}
case AttrState.BeforeValue: {
if (endOfUnquotedValueChars.includes(char) && spaces.includes(char)) {
if (isBeforeValueStarted) {
spacesBeforeAttrName += char;
break;
}
spacesAfterEqual += char;
break;
}
quoteTypeIndex = quoteSet.findIndex(quote => quote.start === char);
const quote = quoteSet[quoteTypeIndex];
if (quote) {
quoteStart = quote.start;
state = AttrState.Value;
break;
}
const raw = char + chars.join('');
const inQuote = quoteInValueChars.find(quote => raw.startsWith(quote.start));
if (inQuote) {
quoteModeStack.push(inQuote);
attrValue += inQuote.start;
chars.splice(0, inQuote.start.length - 1);
state = AttrState.Value;
break;
}
chars.unshift(char);
state = AttrState.Value;
break;
}
case AttrState.Value: {
if (!quoteSet[quoteTypeIndex] && endOfUnquotedValueChars.includes(char)) {
chars.unshift(char);
state = AttrState.AfterValue;
break;
}
if (quoteModeStack.length === 0 && char === quoteSet[quoteTypeIndex]?.end) {
quoteEnd = char;
state = AttrState.AfterValue;
break;
}
const raw = char + chars.join('');
const inQuoteEnd = quoteModeStack.at(-1);
if (inQuoteEnd && raw.startsWith(inQuoteEnd.end)) {
quoteModeStack.pop();
attrValue += inQuoteEnd.end;
chars.splice(0, inQuoteEnd.end.length - 1);
break;
}
const inQuoteStart = quoteInValueChars.find(quote => raw.startsWith(quote.start));
if (inQuoteStart) {
quoteModeStack.push(inQuoteStart);
attrValue += inQuoteStart.start;
chars.splice(0, inQuoteStart.start.length - 1);
break;
}
attrValue += char;
break;
}
}
}
if (state === AttrState.Value && quoteTypeIndex !== -1) {
throw new SyntaxError(`Unclosed attribute value: ${raw}`);
}
const leftover = chars.join('');
return {
spacesBeforeAttrName,
attrName,
spacesBeforeEqual,
equal,
spacesAfterEqual,
startQuote,
value,
endQuote,
isDuplicatable: false,
nodeName: name.raw,
parentNode: null,
prevNode: null,
nextNode: null,
isFragment: false,
isGhost: false,
quoteStart,
attrValue,
quoteEnd,
leftover,
};
if (parsed.leftover) {
return {
...result,
__leftover: parsed.leftover,
};
}
return result;
}

@@ -14,4 +14,5 @@ export declare const MASK_CHAR = "\uE000";

* - U+000C FORM FEED (FF) => `\f`
* - U+000D CARRIAGE RETURN (CR) => `\r`
* - U+0020 SPACE => ` `
*/
export declare const defaultSpaces: readonly ["\t", "\n", "\f", " "];
export declare const defaultSpaces: readonly ["\t", "\n", "\f", "\r", " "];

@@ -103,4 +103,5 @@ export const MASK_CHAR = '\uE000';

* - U+000C FORM FEED (FF) => `\f`
* - U+000D CARRIAGE RETURN (CR) => `\r`
* - U+0020 SPACE => ` `
*/
export const defaultSpaces = ['\t', '\n', '\f', ' '];
export const defaultSpaces = ['\t', '\n', '\f', '\r', ' '];
import type { MLASTAttr, MLASTNode } from '@markuplint/ml-ast';
export declare function nodeListToDebugMaps(nodeList: MLASTNode[], withAttr?: boolean): string[];
export declare function attributesToDebugMaps(attributes: MLASTAttr[]): string[][];
export declare function nodeListToDebugMaps(nodeList: readonly (MLASTNode | null)[], withAttr?: boolean): string[];
export declare function attributesToDebugMaps(attributes: readonly MLASTAttr[]): string[][];
export declare function nodeTreeDebugView(nodeTree: readonly MLASTNode[]): (string | undefined)[];

@@ -1,21 +0,12 @@

export function nodeListToDebugMaps(
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
nodeList, withAttr = false) {
export function nodeListToDebugMaps(nodeList, withAttr = false) {
return nodeList.flatMap(n => {
const r = [];
if (n.isGhost) {
r.push(`[N/A]>[N/A](N/A)${n.nodeName}: ${visibleWhiteSpace(n.raw)}`);
r.push(tokenDebug(n));
if (withAttr && n && n.type === 'starttag') {
r.push(...attributesToDebugMaps(n.attributes).flat());
}
else {
r.push(tokenDebug(n));
if (withAttr && 'attributes' in n) {
r.push(...attributesToDebugMaps(n.attributes).flat());
}
}
return r;
});
}
export function attributesToDebugMaps(
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
attributes) {
export function attributesToDebugMaps(attributes) {
return attributes.map(n => {

@@ -25,12 +16,14 @@ const r = [

...n,
name: n.type === 'html-attr' ? n.name.raw : n.raw,
name: n.type === 'attr' ? n.name.raw : n.raw,
}),
];
if (n.type === 'html-attr') {
r.push(` ${tokenDebug(n.spacesBeforeName, 'bN')}`, ` ${tokenDebug(n.name, 'name')}`, ` ${tokenDebug(n.spacesBeforeEqual, 'bE')}`, ` ${tokenDebug(n.equal, 'equal')}`, ` ${tokenDebug(n.spacesAfterEqual, 'aE')}`, ` ${tokenDebug(n.startQuote, 'sQ')}`, ` ${tokenDebug(n.value, 'value')}`, ` ${tokenDebug(n.endQuote, 'eQ')}`, ` isDirective: ${!!n.isDirective}`, ` isDynamicValue: ${!!n.isDynamicValue}`);
if (n.type === 'spread') {
r.push(` #spread: ${visibleWhiteSpace(n.raw)}`);
return r;
}
r.push(` ${tokenDebug(n.spacesBeforeName, 'bN')}`, ` ${tokenDebug(n.name, 'name')}`, ` ${tokenDebug(n.spacesBeforeEqual, 'bE')}`, ` ${tokenDebug(n.equal, 'equal')}`, ` ${tokenDebug(n.spacesAfterEqual, 'aE')}`, ` ${tokenDebug(n.startQuote, 'sQ')}`, ` ${tokenDebug(n.value, 'value')}`, ` ${tokenDebug(n.endQuote, 'eQ')}`, ` isDirective: ${!!n.isDirective}`, ` isDynamicValue: ${!!n.isDynamicValue}`);
if (n.potentialName != null) {
r.push(` potentialName: ${visibleWhiteSpace(n.potentialName)}`);
}
if (n.type === 'html-attr' && n.candidate) {
if (n.candidate) {
r.push(` candidate: ${visibleWhiteSpace(n.candidate)}`);

@@ -41,6 +34,29 @@ }

}
export function nodeTreeDebugView(nodeTree) {
return nodeTree
.map((n, i) => {
const lines = [];
if (n.type === 'attr' || n.type === 'spread') {
return;
}
lines.push(`${i.toString().padStart(3, '0')}: [${n.uuid.slice(0, 8)}] ${' '.repeat(Math.max(n.depth, 0))}${n.type === 'endtag' ? '/' : ''}${n.nodeName}(${n.uuid.slice(0, 8)})${n.type === 'starttag' && n.isGhost ? '[👻]' : ''}${n.type === 'starttag'
? ` => ${n.pairNode ? `/${n.pairNode.nodeName}(${n.pairNode.uuid.slice(0, 8)})` : '💀'}`
: ''}`);
if (n.type === 'starttag' || n.type === 'psblock') {
for (const c of n.childNodes ?? []) {
lines.push(`${' '.repeat(15)} ${' '.repeat(Math.max(n.depth, 0))}┗━ ${c.type === 'endtag' ? '/' : ''}${c.nodeName}(${c.uuid.slice(0, 8)})`);
}
}
return lines;
})
.filter(Boolean)
.flat();
}
function tokenDebug(n, type = '') {
if (!n) {
return 'NULL';
}
return `[${n.startLine}:${n.startCol}]>[${n.endLine}:${n.endCol}](${n.startOffset},${n.endOffset})${
// @ts-ignore
n.potentialName ?? n.nodeName ?? n.name ?? n.type ?? type}: ${visibleWhiteSpace(n.raw)}`;
n.potentialName ?? n.nodeName ?? n.name ?? n.type ?? type}${'isGhost' in n && n.isGhost ? '(👻)' : ''}${'isBogus' in n && n.isBogus ? '(👿)' : ''}: ${visibleWhiteSpace(n.raw)}`;
}

@@ -47,0 +63,0 @@ function visibleWhiteSpace(chars) {

@@ -1,13 +0,4 @@

export declare function getLine(html: string, startOffset: number): number;
export declare function getCol(html: string, startOffset: number): number;
export declare function getEndLine(html: string, line: number): number;
export declare function getEndCol(html: string, col: number): number;
export declare function sliceFragment(rawHtml: string, start: number, end: number): {
startOffset: number;
endOffset: number;
startLine: number;
endLine: number;
startCol: number;
endCol: number;
raw: string;
};
export declare function getLine(rawCodeFragment: string, startOffset: number): number;
export declare function getCol(rawCodeFragment: string, startOffset: number): number;
export declare function getEndLine(rawCodeFragment: string, startLine: number): number;
export declare function getEndCol(rawCodeFragment: string, startCol: number): number;

@@ -1,28 +0,17 @@

export function getLine(html, startOffset) {
return html.slice(0, startOffset).split(/\n/).length;
const LINE_BREAK = '\n';
export function getLine(rawCodeFragment, startOffset) {
return rawCodeFragment.slice(0, startOffset).split(LINE_BREAK).length;
}
export function getCol(html, startOffset) {
const lines = html.slice(0, startOffset).split(/\n/);
export function getCol(rawCodeFragment, startOffset) {
const lines = rawCodeFragment.slice(0, startOffset).split(LINE_BREAK);
return (lines.at(-1) ?? '').length + 1;
}
export function getEndLine(html, line) {
return html.split(/\r?\n/).length - 1 + line;
export function getEndLine(rawCodeFragment, startLine) {
return rawCodeFragment.split(LINE_BREAK).length - 1 + startLine;
}
export function getEndCol(html, col) {
const lines = html.split(/\r?\n/);
export function getEndCol(rawCodeFragment, startCol) {
const lines = rawCodeFragment.split(LINE_BREAK);
const lineCount = lines.length;
const lastLine = lines.pop();
return lineCount > 1 ? lastLine.length + 1 : col + html.length;
return lineCount > 1 ? lastLine.length + 1 : startCol + rawCodeFragment.length;
}
export function sliceFragment(rawHtml, start, end) {
const raw = rawHtml.slice(start, end);
return {
startOffset: start,
endOffset: end,
startLine: getLine(rawHtml, start),
endLine: getLine(rawHtml, end),
startCol: getCol(rawHtml, start),
endCol: getCol(rawHtml, end),
raw,
};
}

@@ -0,4 +1,5 @@

import type { Parser } from './parser.js';
import type { IgnoreBlock, IgnoreTag } from './types.js';
import type { MLASTNode } from '@markuplint/ml-ast';
import type { MLASTNodeTreeItem } from '@markuplint/ml-ast';
export declare function ignoreBlock(source: string, tags: readonly IgnoreTag[], maskChar?: string): IgnoreBlock;
export declare function restoreNode(nodeList: MLASTNode[], ignoreBlock: IgnoreBlock): MLASTNode[];
export declare function restoreNode(parser: Parser<any, any>, nodeList: readonly MLASTNodeTreeItem[], ignoreBlock: IgnoreBlock, throwErrorWhenTagHasUnresolved?: boolean): MLASTNodeTreeItem[];
import { MASK_CHAR } from './const.js';
import { uuid } from './create-token.js';
import { sliceFragment } from './get-location.js';
import { siblingsCorrection } from './siblings-correction.js';
import { getCol, getLine } from './get-location.js';
import { ParserError } from './parser-error.js';
export function ignoreBlock(source, tags, maskChar = MASK_CHAR) {

@@ -9,12 +8,2 @@ let replaced = source;

for (const tag of tags) {
// Replace tags in attributes
const attr = maskText(prepend(tag.start, '(?<=(?:"|\'))'), append(tag.end, '(?=(?:"|\'))'), replaced, (startTag, taggedCode, endTag) => {
const mask = maskChar.repeat(startTag.length) +
taggedCode.replaceAll(/[^\n]/g, maskChar) +
maskChar.repeat((endTag ?? '').length);
return mask;
});
replaced = attr.replaced;
stack.push(...attr.stack.map(res => ({ ...res, type: tag.type })));
// Replace tags in other nodes
const text = maskText(tag.start, tag.end, replaced, (startTag, taggedCode, endTag) => {

@@ -53,2 +42,3 @@ const mask = maskChar.repeat(startTag.length) +

endTag: endTag ?? null,
resolved: false,
});

@@ -67,102 +57,37 @@ /**

// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
nodeList, ignoreBlock) {
nodeList = [...nodeList];
parser, nodeList,
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
ignoreBlock, throwErrorWhenTagHasUnresolved = true) {
const newNodeList = [...nodeList];
const { source, stack, maskChar } = ignoreBlock;
for (const node of nodeList) {
if (node.type === 'comment' || node.type === 'text' || node.type === 'psblock') {
if (!hasIgnoreBlock(node.raw, maskChar)) {
continue;
}
const parentNode = node.parentNode;
const index = nodeList.indexOf(node);
const insertList = [];
let text = node.raw;
let pointer = 0;
for (const tag of stack) {
if (node.startOffset <= tag.index && tag.index < node.endOffset) {
const start = tag.index - node.startOffset;
const body = tag.startTag + tag.taggedCode + (tag.endTag ?? '');
const above = node.raw.slice(pointer, start);
const below = text.slice(above.length + body.length);
if (above) {
const offset = node.startOffset + pointer;
const { raw, startOffset, endOffset, startLine, endLine, startCol, endCol } = sliceFragment(source, offset, offset + above.length);
const textNode = {
...node,
uuid: uuid(),
type: 'text',
raw,
startOffset,
endOffset,
startLine,
endLine,
startCol,
endCol,
};
if (node.prevNode?.nextNode) {
node.prevNode.nextNode = textNode;
}
if (node.nextNode?.prevNode) {
node.nextNode.prevNode = textNode;
}
insertList.push(textNode);
}
if (body) {
const offset = node.startOffset + pointer + above.length;
const { raw, startOffset, endOffset, startLine, endLine, startCol, endCol } = sliceFragment(source, offset, offset + body.length);
const bodyNode = {
uuid: uuid(),
type: 'psblock',
nodeName: `#ps:${tag.type}`,
raw,
parentNode: node.parentNode,
prevNode: null,
nextNode: null,
isFragment: node.isFragment,
isGhost: false,
startOffset,
endOffset,
startLine,
endLine,
startCol,
endCol,
};
if (node.prevNode?.nextNode) {
node.prevNode.nextNode = bodyNode;
}
if (node.nextNode?.prevNode) {
node.nextNode.prevNode = bodyNode;
}
insertList.push(bodyNode);
}
text = below;
pointer = start + body.length;
}
}
if (text) {
const offset = node.endOffset - text.length;
const { raw, startOffset, endOffset, startLine, endLine, startCol, endCol } = sliceFragment(source, offset, offset + text.length);
const textNode = {
...node,
uuid: uuid(),
type: 'text',
raw,
startOffset,
endOffset,
startLine,
endLine,
startCol,
endCol,
};
insertList.push(textNode);
}
siblingsCorrection(insertList);
if (parentNode) {
parentNode.childNodes = insertList;
}
nodeList.splice(index, 1, ...insertList);
if (stack.length === 0) {
return newNodeList;
}
for (const tag of stack) {
const node = newNodeList.find(node => node.startOffset === tag.index);
if (!node) {
continue;
}
const raw = `${tag.startTag}${tag.taggedCode}${tag.endTag ?? ''}`;
const token = parser.createToken(raw, node.startOffset, node.startLine, node.startCol);
const psNode = {
...token,
type: 'psblock',
depth: node.depth,
nodeName: `#ps:${tag.type}`,
parentNode: node.parentNode,
childNodes: [],
isBogus: false,
};
if (node.type !== 'doctype' && node.parentNode?.childNodes) {
parser.replaceChild(node.parentNode, node, psNode);
}
const index = newNodeList.indexOf(node);
newNodeList.splice(index, 1, psNode);
tag.resolved = true;
}
for (const node of newNodeList) {
if (node.type === 'starttag') {
for (const attr of node.attributes) {
if (attr.type === 'ps-attr' || attr.value.raw === '' || !hasIgnoreBlock(attr.value.raw, maskChar)) {
if (attr.type === 'spread' || attr.value.raw === '' || !hasIgnoreBlock(attr.value.raw, maskChar)) {
continue;

@@ -177,10 +102,35 @@ }

const below = attr.value.raw.slice(offset + length);
attr.value.raw = above + raw + below;
attr.isDynamicValue = true;
parser.updateRaw(attr.value, above + raw + below);
parser.updateAttr(attr, { isDynamicValue: true });
tag.resolved = true;
}
parser.updateRaw(attr, attr.name.raw +
attr.spacesBeforeEqual.raw +
attr.equal.raw +
attr.spacesAfterEqual.raw +
attr.startQuote.raw +
attr.value.raw +
attr.endQuote.raw);
}
// Update node raw
const length = attr.raw.length;
const offset = attr.startOffset - node.startOffset;
const above = node.raw.slice(0, offset);
const below = node.raw.slice(offset + length);
parser.updateRaw(node, above + attr.raw + below);
}
}
}
return nodeList;
if (throwErrorWhenTagHasUnresolved) {
for (const tag of stack) {
if (!tag.resolved) {
throw new ParserError('Parsing failed. Unsupported syntax detected', {
line: getLine(source, tag.index),
col: getCol(source, tag.index),
raw: tag.startTag + tag.taggedCode + (tag.endTag ?? ''),
});
}
}
}
return newNodeList;
}

@@ -204,14 +154,2 @@ function snap(str, reg) {

}
function prepend(reg, str) {
if (typeof reg === 'string') {
return new RegExp(str + escapeRegExpForStr(reg));
}
return new RegExp(str + reg.source, reg.ignoreCase ? 'i' : '');
}
function append(reg, str) {
if (typeof reg === 'string') {
return new RegExp(escapeRegExpForStr(reg) + str);
}
return new RegExp(reg.source + str, reg.ignoreCase ? 'i' : '');
}
function hasIgnoreBlock(textContent, maskChar) {

@@ -218,0 +156,0 @@ return textContent.includes(maskChar);

@@ -1,1 +0,4 @@

export declare function ignoreFrontMatter(code: string): string;
export declare function ignoreFrontMatter(code: string): {
code: string;
frontMatter: string | null;
};
export function ignoreFrontMatter(code) {
const reStart = /^(?:\s*\n)?---\r?\n/.exec(code);
if (!reStart) {
return code;
return {
code,
frontMatter: null,
};
}

@@ -10,3 +13,6 @@ const startPoint = reStart[0].length;

if (!reEnd) {
return code;
return {
code,
frontMatter: null,
};
}

@@ -17,3 +23,6 @@ const endPoint = startPoint + reEnd.index + reEnd[0].length;

const masked = frontMatter.replaceAll(/[^\n\r]/g, ' ');
return masked + afterCode;
return {
code: masked + afterCode,
frontMatter,
};
}

@@ -1,20 +0,7 @@

export * from './attr-parser.js';
export * from './attr-tokenizer.js';
export * from './const.js';
export * from './create-token.js';
export * from './debugger.js';
export * from './decision.js';
export * from './detect-element-type.js';
export * from './flatten-nodes.js';
export * from './get-location.js';
export * from './get-space-before.js';
export * from './enums.js';
export * from './idl-attributes.js';
export * from './ignore-block.js';
export * from './ignore-front-matter.js';
export * from './parse-attr.js';
export * from './parser-error.js';
export * from './remove-deprecated-node.js';
export * from './parser.js';
export * from './script-parser.js';
export * from './tag-parser.js';
export * from './tag-splitter.js';
export * from './walker.js';
export * from './types.js';

@@ -1,20 +0,7 @@

export * from './attr-parser.js';
export * from './attr-tokenizer.js';
export * from './const.js';
export * from './create-token.js';
export * from './debugger.js';
export * from './decision.js';
export * from './detect-element-type.js';
export * from './flatten-nodes.js';
export * from './get-location.js';
export * from './get-space-before.js';
export * from './enums.js';
export * from './idl-attributes.js';
export * from './ignore-block.js';
export * from './ignore-front-matter.js';
export * from './parse-attr.js';
export * from './parser-error.js';
export * from './remove-deprecated-node.js';
export * from './parser.js';
export * from './script-parser.js';
export * from './tag-parser.js';
export * from './tag-splitter.js';
export * from './walker.js';
export * from './types.js';

@@ -5,2 +5,3 @@ export type ParserErrorInfo = {

readonly raw?: string;
readonly stack?: string;
};

@@ -7,0 +8,0 @@ export declare class ParserError extends Error {

@@ -8,2 +8,3 @@ export class ParserError extends Error {

this.raw = info.raw ?? '';
this.stack = info.stack ?? this.stack;
}

@@ -10,0 +11,0 @@ }

@@ -1,2 +0,2 @@

export declare function scriptParser(script: string): any;
export declare function scriptParser(script: string): ScriptTokenType[];
export declare function removeQuote(str: string): string;

@@ -3,0 +3,0 @@ export type ScriptTokenType = {

@@ -15,3 +15,3 @@ // @ts-ignore

const quote = str[0];
if (quote !== '"' && quote !== "'") {
if (quote !== '"' && quote !== "'" && quote !== '`') {
return str;

@@ -18,0 +18,0 @@ }

@@ -0,1 +1,34 @@

import type { EndTagType, MLASTParentNode, ParserOptions as ConfigParserOptions } from '@markuplint/ml-ast';
export type ParserOptions = {
readonly booleanish?: boolean;
readonly endTagType?: EndTagType;
readonly ignoreTags?: readonly IgnoreTag[];
readonly maskChar?: string;
readonly tagNameCaseSensitive?: boolean;
readonly selfCloseType?: SelfCloseType;
readonly spaceChars?: readonly string[];
readonly rawTextElements?: readonly string[];
};
export type ParseOptions = ConfigParserOptions & {
readonly offsetOffset?: number;
readonly offsetLine?: number;
readonly offsetColumn?: number;
readonly depth?: number;
};
export type Tokenized<N extends {} = {}, State extends unknown = null> = {
readonly ast: N[];
readonly isFragment: boolean;
readonly state?: State;
};
export type Token = {
readonly raw: string;
readonly startOffset: number;
readonly startLine: number;
readonly startCol: number;
};
export type ChildToken = Token & {
readonly depth: number;
readonly parentNode: MLASTParentNode | null;
};
export type SelfCloseType = 'html' | 'xml' | 'html+xml';
export type Code = {

@@ -7,2 +40,3 @@ readonly type: string;

readonly endTag: string | null;
resolved: boolean;
};

@@ -9,0 +43,0 @@ export type IgnoreTag = {

{
"name": "@markuplint/parser-utils",
"version": "4.0.0-dev.10+b28398ab",
"version": "4.0.0-dev.12+2275fbeb0",
"description": "Utility module for markuplint parser plugin",

@@ -13,2 +13,5 @@ "repository": "git@github.com:markuplint/markuplint.git",

"import": "./lib/index.js"
},
"./location": {
"import": "./lib/get-location.js"
}

@@ -28,10 +31,11 @@ },

"dependencies": {
"@markuplint/ml-ast": "4.0.0-dev.10+b28398ab",
"@markuplint/types": "4.0.0-dev.10+b28398ab",
"@markuplint/ml-ast": "4.0.0-dev.12+2275fbeb0",
"@markuplint/ml-spec": "4.0.0-dev.12+2275fbeb0",
"@markuplint/types": "4.0.0-dev.12+2275fbeb0",
"@types/uuid": "^9.0.7",
"espree": "^9.6.1",
"type-fest": "^4.8.3",
"type-fest": "^4.9.0",
"uuid": "^9.0.1"
},
"gitHead": "b28398ab9c8f0ad790f2915ad5da8f3a80e9b8d6"
"gitHead": "2275fbeb053605b636f080f4fafd7cd4fc57a9a3"
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc