UNPKG

yini-parser

Version:

Node.js parser for YINI — a clean, structured INI alternative with types, simple section nesting, comments, and strict mode.

104 lines (103 loc) 4.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const print_1 = require("../utils/print"); const yiniHelpers_1 = require("../yiniHelpers"); const extractSignificantYiniLine_1 = require("./extractSignificantYiniLine"); /** * Check and identify the section header parts via tokenizing the parts and return them as strings. * @param rawHeaderLine Raw line with the section header where the header * marker will be identified. E.g. does the header start with '^^^' or '^3' * and then some identifier. * * Below, copied from YINI Specification v1.0.0 Beta 7. * Form 1: Identifier of Simple Form: * - Keys must be non-empty. * - Keys are case-sensitive (`Title` and `title` are different). * - Can only contain letters (a-z or A-Z), digits (0-9) and underscores `_`. * - Must begin with a letter or an underscore `_`. * - Note: Cannot contain hyphens (`-`) or periods (`.`). * * Form 2: Backticked Identifier: * - A phrase is a name wrapped in backticks ``` ` ```. * - Backticked identifiers must be on a single line and must not contain tabs or new lines unless using escaping codes, except for ordinary spaces. * - Special control characters (U+0000–U+001F) must be escaped. * * @note Returns the parts as strings; each part needs to be analyzed separately against the contraints in the specifications. * @returns An object with the identified header parts: marker characters, parsed name, and parsed level string. */ const extractHeaderParts = (rawLine, errorHandler = null, ctx = null) => { (0, print_1.debugPrint)('-> Entered extractHeaderParts(..)'); rawLine = rawLine.trim(); const str = (0, extractSignificantYiniLine_1.extractYiniLine)(rawLine); (0, print_1.debugPrint)('rawLine: >>>' + rawLine + '<<<'); (0, print_1.debugPrint)(' str: >>>' + str + '<<<'); // Edge case: empty line. if (!str) { errorHandler.pushOrBail(ctx, 'Internal-Error', 'Received blank argument in extractHeaderParts(..)', 'Sorry, an unintended internal error happened.'); } let pos = 0; const len = str.length; let markerCharsPart = ''; let numberPart = ''; let sectionNamePart = ''; let isBacktickedName = false; // 1. Skip leading whitespace. while (pos < len && (str[pos] === ' ' || str[pos] === '\t')) pos++; // 2. Collect marker(s): ^, <, §, €. while (pos < len && (0, yiniHelpers_1.isMarkerCharacter)(str[pos])) { markerCharsPart += str[pos]; pos++; } // 3. Numeric part (for numeric shorthand; only if single marker found). if (markerCharsPart.length === 1 && pos < len && str[pos] >= '1' && str[pos] <= '9') { // Start collecting number part. while (pos < len && str[pos] >= '0' && str[pos] <= '9') { numberPart += str[pos]; pos++; } markerCharsPart += numberPart; // E.g., "^7". } // 4. Skip whitespace between marker and section name. while (pos < len && (str[pos] === ' ' || str[pos] === '\t')) pos++; // 5. Collect section name (identifier or backticked). if (pos < len && str[pos] === '`') { // Backticked identifier. let start = pos; pos++; // Skip initial backtick. while (pos < len && str[pos] !== '`') pos++; pos++; // Include the closing backtick (if found). sectionNamePart = str.slice(start, pos).trim(); isBacktickedName = true; } else { // Non-backticked: take the rest of the line, trim off any trailing comments, etc. sectionNamePart = str.slice(pos).trim(); // Optionally, strip trailing comments or newlines here if needed. } if (isBacktickedName) { (0, print_1.debugPrint)('Backticed sectionNamePart: ' + sectionNamePart); // sectionNamePart = trimBackticks(sectionNamePart) } (0, print_1.debugPrint)(); (0, print_1.debugPrint)('------'); (0, print_1.debugPrint)('<- About to leave extractHeaderParts(..)'); (0, print_1.debugPrint)(); (0, print_1.debugPrint)(' markerCharsPart: >>>' + markerCharsPart + '<<<'); (0, print_1.debugPrint)(' sectionNamePart: >>>' + sectionNamePart + '<<<'); (0, print_1.debugPrint)(' numberPart: >>>' + numberPart + '<<<'); (0, print_1.debugPrint)(' isBacktickedName: ' + isBacktickedName); (0, print_1.debugPrint)(); return { strMarkerChars: markerCharsPart, strSectionName: sectionNamePart, strNumberPart: numberPart, isBacktickedName, }; }; exports.default = extractHeaderParts;