promisified-properties
Version:
Handle .properties file via promisified and typed API
109 lines (108 loc) • 3.56 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parse = exports.PropertiesParser = void 0;
const parsimmon_1 = __importDefault(require("parsimmon"));
/**
* Append a line-break to the end of line, if the end of line is not escaped by '\'
*/
function appendLineBreak(line) {
if (/(^|[^\\])(\\\\)*\\$/.test(line)) {
return line.substring(0, line.length - 1);
}
else {
return line + "\n";
}
}
function interpretEscapes(str) {
return str.replace(/\\(u[0-9a-fA-F]{4}|[^u])/g, (_, escape) => {
const type = escape.charAt(0);
if (type === "u") {
const hex = escape.slice(1);
return String.fromCharCode(parseInt(hex, 16));
}
switch (type) {
case "f":
return "\f";
case "n":
return "\n";
case "r":
return "\r";
case "t":
return "\t";
}
return type;
});
}
exports.PropertiesParser = parsimmon_1.default.createLanguage({
/**
* WhiteSpace defined in the spec
*/
WhiteSpace: (r) => {
return parsimmon_1.default.regexp(/( |\f|\t|\\u0009|\\u0020|\\u000C)*/);
},
NaturalLine: (r) => {
return r.BrankLine.map((_) => "").or(parsimmon_1.default.regexp(/.*/));
},
/**
* The natural line that contains only white space characters.
* Ignored by parser.
*/
BrankLine: (r) => {
return parsimmon_1.default.regexp(/^( |\f|\t|\\u0009|\\u0020|\\u000C)*$/);
},
/**
* The natural line that has an ASCII '#' or '!' as its first non-white space character.
* Ignored by parser.
*/
CommentLine: (r) => {
return parsimmon_1.default.regexp(/^[!#].*/).trim(r.WhiteSpace);
},
LogicalLine: (r) => {
const p1 = parsimmon_1.default.seqObj(["key", r.Key.trim(r.WhiteSpace)], r.KeyTerminator, ["value", r.Value.trim(r.WhiteSpace)]);
const p2 = parsimmon_1.default.seqObj(["key", r.Key.trim(r.WhiteSpace)], r.WhiteSpace);
const p3 = parsimmon_1.default.seqObj(["text", r.Comment]);
return p1.or(p2).or(p3);
},
/**
* Key terminator defined in the spec
*/
KeyTerminator: (r) => {
return parsimmon_1.default.oneOf(":=");
},
Key: (r) => {
return parsimmon_1.default.regexp(/([a-zA-Z0-9_.-]|\\u[a-z0-9]{4}|\\[\\a-zA-Z0-9=:])+/)
.trim(r.WhiteSpace)
.map(interpretEscapes);
},
Value: (r) => {
return parsimmon_1.default.all.trim(r.WhiteSpace).map(interpretEscapes);
},
Comment: (r) => {
return parsimmon_1.default.all.map(interpretEscapes);
},
});
function parse(s) {
const logicalLines = exports.PropertiesParser.NaturalLine.sepBy(parsimmon_1.default.newline)
.map((naturalLines) => {
return naturalLines
.map(appendLineBreak)
.join("")
.split("\n")
.filter((s) => s.length > 0);
})
.tryParse(s);
const logicalLineParser = exports.PropertiesParser.LogicalLine;
return logicalLines.map((logicalLine) => {
const result = logicalLineParser.tryParse(logicalLine);
if ("value" in result) {
return { key: result.key, value: result.value?.trim() };
}
else {
return result;
}
});
}
exports.parse = parse;