UNPKG

@gulujs/toml

Version:

TOML parser and serializer

133 lines (132 loc) 4.91 kB
import { RE_ONE_QUOTE, RE_THREE_DOUBLE_QUOTES, RE_THREE_DOUBLE_QUOTES_END, RE_THREE_SINGLE_QUOTES, RE_THREE_SINGLE_QUOTES_END } from '../constants.js'; import { SYNTAX_ERROR_MESSAGE } from '../../errors/index.js'; export function getString(source, offset) { let str = getStringInThreeSingleQuotes(source, offset); if (str === null) { str = getStringInThreeDoubleQuotes(source, offset); if (str === null) { str = getStringInOneQuote(source, offset); } } return str; } function getStringInThreeSingleQuotes(source, offset) { RE_THREE_SINGLE_QUOTES.lastIndex = offset; const matches = RE_THREE_SINGLE_QUOTES.exec(source.line); if (!matches || matches.index !== offset) { return null; } if (matches[3]) { source.assertValidString(matches[2], offset + matches[1].length); return createThreeQuotesValueResult(matches[2], RE_THREE_SINGLE_QUOTES.lastIndex, '\'', source); } if (!matches[4]) { throw new SyntaxError(SYNTAX_ERROR_MESSAGE(source, offset + matches[1].length)); } let value = ''; if (matches[2]) { source.assertValidString(matches[2], offset + matches[1].length); value = matches[2] + matches[4]; } let nextIndex = RE_THREE_SINGLE_QUOTES.lastIndex; while (source.next()) { nextIndex = 0; RE_THREE_SINGLE_QUOTES_END.lastIndex = nextIndex; const matches = RE_THREE_SINGLE_QUOTES_END.exec(source.line); if (!matches) { source.assertValidString(source.line, 0); value += source.line; continue; } source.assertValidString(matches[1], 0); value += matches[1]; return createThreeQuotesValueResult(value, RE_THREE_SINGLE_QUOTES_END.lastIndex, '\'', source); } throw new SyntaxError(SYNTAX_ERROR_MESSAGE(source, nextIndex)); } function getStringInThreeDoubleQuotes(source, offset) { RE_THREE_DOUBLE_QUOTES.lastIndex = offset; const matches = RE_THREE_DOUBLE_QUOTES.exec(source.line); if (!matches || matches.index !== offset) { return null; } if (matches[3]) { const strOffset = offset + matches[1].length; source.assertValidString(matches[2], strOffset); return createThreeQuotesValueResult(source.unescapeString(matches[2], strOffset), RE_THREE_DOUBLE_QUOTES.lastIndex, '"', source); } if (!matches[5]) { throw new SyntaxError(SYNTAX_ERROR_MESSAGE(source, offset + matches[1].length)); } let nextLineTrimStart = !!matches[4]; let value = ''; if (matches[2]) { const strOffset = offset + matches[1].length; source.assertValidString(matches[2], strOffset); value = source.unescapeString(matches[2], strOffset); if (!nextLineTrimStart) { value += matches[5]; } } let nextIndex = RE_THREE_DOUBLE_QUOTES.lastIndex; while (source.next()) { nextIndex = 0; RE_THREE_DOUBLE_QUOTES_END.lastIndex = nextIndex; const matches = RE_THREE_DOUBLE_QUOTES_END.exec(source.line); if (!matches) { throw new SyntaxError(SYNTAX_ERROR_MESSAGE(source, nextIndex)); } if (nextLineTrimStart && !matches[2] && !matches[3]) { continue; } if (!nextLineTrimStart) { value += matches[1]; } if (matches[2]) { const strOffset = matches[1].length; source.assertValidString(matches[2], strOffset); value += source.unescapeString(matches[2], strOffset); } if (matches[3]) { return createThreeQuotesValueResult(value, RE_THREE_DOUBLE_QUOTES_END.lastIndex, '"', source); } nextLineTrimStart = !!matches[4]; if (!nextLineTrimStart) { value += matches[5]; } } throw new SyntaxError(SYNTAX_ERROR_MESSAGE(source, nextIndex)); } function createThreeQuotesValueResult(value, nextIndex, quote, source) { if (source.line[nextIndex] === quote) { value += quote; nextIndex += 1; if (source.line[nextIndex] === quote) { value += quote; nextIndex += 1; } } return { value, nextIndex }; } function getStringInOneQuote(source, offset) { RE_ONE_QUOTE.lastIndex = offset; const matches = RE_ONE_QUOTE.exec(source.line); if (!matches || matches.index !== offset) { return null; } const strOffset = offset + matches[1].length + 1; if (matches[2]) { source.assertValidString(matches[2], strOffset); return { value: matches[2], nextIndex: RE_ONE_QUOTE.lastIndex }; } else { source.assertValidString(matches[3], strOffset); return { value: source.unescapeString(matches[3], strOffset), nextIndex: RE_ONE_QUOTE.lastIndex }; } }