2
0
mirror of https://github.com/tenrok/BBob.git synced 2026-05-15 11:59:37 +03:00
Files
bbob/packages/bbob-parser/src/utils.js
T
Nikolay Kostyurin 8cb1d495dd refactor(parser): better jsdoc, some behavior fixes, more tests
— all operations on nodes moved to `createList` function
- fixed problem with single tags with value only like `[url=value]` fixes #6
- write tests for `Token` class
- moved all node arrays to parse func, now parser supports many instances
- add jsdoc to critical parts of the parser to better understanding how it works
2019-03-04 02:24:12 +02:00

147 lines
2.8 KiB
JavaScript

import {
QUOTEMARK,
BACKSLASH,
} from '@bbob/plugin-helper/lib/char';
/**
* @typedef {Object} CharGrabber
* @property {Function} skip
* @property {Function} hasNext
* @property {Function} isLast
* @property {Function} grabWhile
*/
/**
* Creates a grabber wrapper for source string, that helps to iterate over string char by char
* @param {String} source
* @param {Function} onSkip
* @returns
*/
export const createCharGrabber = (source, { onSkip } = {}) => {
let idx = 0;
const skip = () => {
idx += 1;
if (onSkip) {
onSkip();
}
};
const hasNext = () => source.length > idx;
const getRest = () => source.substr(idx);
const getCurr = () => source[idx];
return {
skip,
hasNext,
isLast: () => (idx === source.length),
grabWhile: (cond) => {
const start = idx;
while (hasNext() && cond(getCurr())) {
skip();
}
return source.substr(start, idx - start);
},
getNext: () => source[idx + 1],
getPrev: () => source[idx - 1],
getCurr,
getRest,
/**
* Grabs rest of string until it find a char
* @param {String} char
* @return {String}
*/
substrUntilChar: (char) => {
const restStr = getRest();
const indexOfChar = restStr.indexOf(char);
if (indexOfChar >= 0) {
return restStr.substr(0, indexOfChar);
}
return '';
},
};
};
/**
* Trims string from start and end by char
* @example
* trimChar('*hello*', '*') ==> 'hello'
* @param {String} str
* @param {String} charToRemove
* @returns {String}
*/
export const trimChar = (str, charToRemove) => {
while (str.charAt(0) === charToRemove) {
// eslint-disable-next-line no-param-reassign
str = str.substring(1);
}
while (str.charAt(str.length - 1) === charToRemove) {
// eslint-disable-next-line no-param-reassign
str = str.substring(0, str.length - 1);
}
return str;
};
/**
* Unquotes \" to "
* @param str
* @return {String}
*/
export const unquote = str => str.replace(BACKSLASH + QUOTEMARK, QUOTEMARK);
/**
* @typedef {Object} ItemList
* @type {Object}
* @property {getLastCb} getLast
* @property {flushLastCb} flushLast
* @property {pushCb} push
* @property {toArrayCb} toArray
*/
/**
*
* @param values
* @return {ItemList}
*/
export const createList = (values = []) => {
const nodes = values;
/**
* @callback getLastCb
*/
const getLast = () => (nodes.length ? nodes[nodes.length - 1] : null);
/**
* @callback flushLastCb
* @return {*}
*/
const flushLast = () => {
if (nodes.length) {
return nodes.pop();
}
return false;
};
/**
* @callback pushCb
* @param value
*/
const push = value => nodes.push(value);
/**
* @callback toArrayCb
* @return {Array}
*/
return {
getLast,
flushLast,
push,
toArray: () => nodes,
};
};