Gazebo_simulation-Frontend/node_modules/yaml/dist/cst/source-utils.js
2020-12-21 10:29:31 -05:00

178 lines
4.2 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getLinePos = getLinePos;
exports.getLine = getLine;
exports.getPrettyContext = getPrettyContext;
function findLineStarts(src) {
const ls = [0];
let offset = src.indexOf('\n');
while (offset !== -1) {
offset += 1;
ls.push(offset);
offset = src.indexOf('\n', offset);
}
return ls;
}
function getSrcInfo(cst) {
let lineStarts, src;
if (typeof cst === 'string') {
lineStarts = findLineStarts(cst);
src = cst;
} else {
if (Array.isArray(cst)) cst = cst[0];
if (cst && cst.context) {
if (!cst.lineStarts) cst.lineStarts = findLineStarts(cst.context.src);
lineStarts = cst.lineStarts;
src = cst.context.src;
}
}
return {
lineStarts,
src
};
}
/**
* @typedef {Object} LinePos - One-indexed position in the source
* @property {number} line
* @property {number} col
*/
/**
* Determine the line/col position matching a character offset.
*
* Accepts a source string or a CST document as the second parameter. With
* the latter, starting indices for lines are cached in the document as
* `lineStarts: number[]`.
*
* Returns a one-indexed `{ line, col }` location if found, or
* `undefined` otherwise.
*
* @param {number} offset
* @param {string|Document|Document[]} cst
* @returns {?LinePos}
*/
function getLinePos(offset, cst) {
if (typeof offset !== 'number' || offset < 0) return null;
const {
lineStarts,
src
} = getSrcInfo(cst);
if (!lineStarts || !src || offset > src.length) return null;
for (let i = 0; i < lineStarts.length; ++i) {
const start = lineStarts[i];
if (offset < start) {
return {
line: i,
col: offset - lineStarts[i - 1] + 1
};
}
if (offset === start) return {
line: i + 1,
col: 1
};
}
const line = lineStarts.length;
return {
line,
col: offset - lineStarts[line - 1] + 1
};
}
/**
* Get a specified line from the source.
*
* Accepts a source string or a CST document as the second parameter. With
* the latter, starting indices for lines are cached in the document as
* `lineStarts: number[]`.
*
* Returns the line as a string if found, or `null` otherwise.
*
* @param {number} line One-indexed line number
* @param {string|Document|Document[]} cst
* @returns {?string}
*/
function getLine(line, cst) {
const {
lineStarts,
src
} = getSrcInfo(cst);
if (!lineStarts || !(line >= 1) || line > lineStarts.length) return null;
const start = lineStarts[line - 1];
let end = lineStarts[line]; // undefined for last line; that's ok for slice()
while (end && end > start && src[end - 1] === '\n') --end;
return src.slice(start, end);
}
/**
* Pretty-print the starting line from the source indicated by the range `pos`
*
* Trims output to `maxWidth` chars while keeping the starting column visible,
* using `…` at either end to indicate dropped characters.
*
* Returns a two-line string (or `null`) with `\n` as separator; the second line
* will hold appropriately indented `^` marks indicating the column range.
*
* @param {Object} pos
* @param {LinePos} pos.start
* @param {LinePos} [pos.end]
* @param {string|Document|Document[]*} cst
* @param {number} [maxWidth=80]
* @returns {?string}
*/
function getPrettyContext({
start,
end
}, cst, maxWidth = 80) {
let src = getLine(start.line, cst);
if (!src) return null;
let {
col
} = start;
if (src.length > maxWidth) {
if (col <= maxWidth - 10) {
src = src.substr(0, maxWidth - 1) + '…';
} else {
const halfWidth = Math.round(maxWidth / 2);
if (src.length > col + halfWidth) src = src.substr(0, col + halfWidth - 1) + '…';
col -= src.length - maxWidth;
src = '…' + src.substr(1 - maxWidth);
}
}
let errLen = 1;
let errEnd = '';
if (end) {
if (end.line === start.line && col + (end.col - start.col) <= maxWidth + 1) {
errLen = end.col - start.col;
} else {
errLen = Math.min(src.length + 1, maxWidth) - col;
errEnd = '…';
}
}
const offset = col > 1 ? ' '.repeat(col - 1) : '';
const err = '^'.repeat(errLen);
return `${src}\n${offset}${err}${errEnd}`;
}