versification
Version:
A library for parsing Paratext's vrs files.
267 lines (266 loc) • 11.8 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VerseRef = void 0;
var Canon_1 = require("./Canon");
var VerseRef_1 = __importDefault(require("./VerseRef"));
exports.VerseRef = VerseRef_1.default;
var LineType;
(function (LineType) {
LineType[LineType["Comment"] = 0] = "Comment";
LineType[LineType["ChapterVerse"] = 1] = "ChapterVerse";
LineType[LineType["StandardMapping"] = 2] = "StandardMapping";
LineType[LineType["OneToManyMapping"] = 3] = "OneToManyMapping";
LineType[LineType["ExcludedVerse"] = 4] = "ExcludedVerse";
LineType[LineType["VerseSegments"] = 5] = "VerseSegments";
})(LineType || (LineType = {}));
var Versification = /** @class */ (function () {
function Versification(vrsData) {
this.name = '';
this._books = [];
this._verseMappings = [];
this._excludedVerses = new Set();
this._verseSegments = {};
this.parseData(vrsData);
}
Versification.nameToFileName = function (versificationName) {
var _a;
if (!versificationName)
return null;
if (versificationName.includes('-'))
versificationName = versificationName.split('-')[0];
var lowerCaseVersificationNameWithoutSpaces = (_a = versificationName.toLowerCase()) === null || _a === void 0 ? void 0 : _a.replace(/\s/g, '');
switch (lowerCaseVersificationNameWithoutSpaces) {
case 'english':
return 'eng';
case 'original':
return 'org';
case 'septuagint':
return 'lxx';
case 'russianprotestant':
return 'rsc';
case 'russianorthodox':
return 'rso';
case 'vulgate':
return 'vul';
}
return null;
};
Versification.bookIdToNumber = function (bookId) {
return (0, Canon_1.bookIdToNumber)(bookId);
};
Versification.prototype.parseData = function (vrsData) {
var _this = this;
vrsData.split('\n').forEach(function (line) { return _this.praseLine(line); });
};
Versification.prototype.lineType = function (line) {
var commentLine = line[0] === '#';
if (commentLine || line.length < 2)
return LineType.Comment;
if (line.includes('=')) {
if (line.includes('&'))
return LineType.OneToManyMapping;
return LineType.StandardMapping;
}
if (line[0] === '-')
return LineType.ExcludedVerse;
if (line[0] === '*')
return LineType.VerseSegments;
return LineType.ChapterVerse;
};
Versification.prototype.praseLine = function (line) {
line = line.trimStart();
if (line.startsWith('#!'))
line = line.substring(2);
line = line.trimStart();
var lineType = this.lineType(line);
switch (lineType) {
case LineType.Comment:
if (!this.name)
this.parseCommentLine(line);
break;
case LineType.ChapterVerse:
this.parseChapterVerseLine(line);
break;
case LineType.StandardMapping:
this.parseStandardMapping(line);
break;
case LineType.OneToManyMapping:
this.parseManyToOneMapping(line);
break;
case LineType.ExcludedVerse:
this.parseExcludedVerse(line);
break;
case LineType.VerseSegments:
this.parseVerseSegments(line);
break;
}
};
Versification.prototype.parseCommentLine = function (line) {
if (!line.includes('Versification'))
return;
var results = line.match(/Versification\s*"(.*)"/);
this.name = (results === null || results === void 0 ? void 0 : results[1]) || '';
};
Versification.prototype.parseChapterVerseLine = function (line) {
var _this = this;
var parts = line.split(' ');
var book = parts[0], rest = parts.slice(1);
var bookNumber = (0, Canon_1.bookIdToNumber)(book);
if (bookNumber === undefined)
return;
rest.forEach(function (chapterVerse) {
var _a = chapterVerse.split(':'), chapter = _a[0], numberOfVerses = _a[1];
if (!_this._books[bookNumber])
_this._books[bookNumber] = [];
_this._books[bookNumber][parseInt(chapter)] = parseInt(numberOfVerses);
});
};
Versification.prototype.parseVerseRange = function (verseRefRange) {
var _a = verseRefRange.trim().split(':'), bookChapter = _a[0], verse = _a[1];
var _b = verse.split('-').map(function (x) { return parseInt(x); }), start = _b[0], end = _b[1];
if (!end) {
var verseRef = VerseRef_1.default.parse(verseRefRange.trim());
if (!verseRef)
return [];
return [verseRef];
}
var verseNumbers = end < start ? [start] : Array.apply(0, Array(end - start + 1)).map(function (_, i) { return i + start; });
var ret = [];
verseNumbers.forEach(function (verseNumber) {
var fromVerseRef = VerseRef_1.default.parse("".concat(bookChapter, ":").concat(verseNumber));
if (fromVerseRef)
ret.push(fromVerseRef);
});
return ret;
};
Versification.prototype.parseStandardMapping = function (line) {
var _this = this;
var _a = line.split('='), from = _a[0], to = _a[1];
if (!from.includes('-')) {
var fromVerseRef = VerseRef_1.default.parse(from.trim());
var toVerseRef = VerseRef_1.default.parse(to.trim());
if (!toVerseRef || !fromVerseRef)
return;
this._verseMappings.push([fromVerseRef, toVerseRef]);
}
else {
var fromVerseRefs = this.parseVerseRange(from);
var toVerseRefs_1 = this.parseVerseRange(to);
fromVerseRefs.forEach(function (fromVerseRef, index) {
// If toVerseRefs has less the fromVerseRefs repeat the final verseref
var toVerse = toVerseRefs_1[index] || toVerseRefs_1[toVerseRefs_1.length - 1];
_this._verseMappings.push([fromVerseRef, toVerse]);
});
}
};
Versification.prototype.removeManyToOneMarker = function (verseRefString) {
return this.removeLeadingChar(verseRefString, '&');
};
Versification.prototype.removeVerseSegmentMarker = function (verseRefString) {
return this.removeLeadingChar(verseRefString, '*');
};
Versification.prototype.removeLeadingChar = function (str, leadingChar) {
if (str.startsWith(leadingChar))
return str.substring(1);
return str;
};
Versification.prototype.parseManyToOneMapping = function (line) {
var _this = this;
var _a = line.split('=').map(function (x) { return x.trim(); }), from = _a[0], to = _a[1];
var fromVerseRefs = this.parseVerseRange(this.removeManyToOneMarker(from));
var toVerseRefs = this.parseVerseRange(to);
fromVerseRefs.forEach(function (fromVerseRef) {
toVerseRefs.forEach(function (toVerseRefs) {
_this._verseMappings.push([fromVerseRef, toVerseRefs]);
});
});
};
Versification.prototype.parseExcludedVerse = function (line) {
var verses = this.parseVerseRange(line.substring(1));
if (!verses[0])
return;
this._excludedVerses.add(verses[0].bbbcccvvv());
};
Versification.prototype.parseVerseSegments = function (line) {
var _a = line.trim().split(','), verseRefStr = _a[0], parts = _a.slice(1);
var verseRef = this.parseVerseRange(this.removeVerseSegmentMarker(verseRefStr))[0];
if (!verseRef)
return;
var segments = [];
parts.forEach(function (part) {
segments.push(part === '-' ? '' : part);
});
this._verseSegments[verseRef.bbbcccvvv()] = segments;
};
// Returns collection of 1 based index arrays (where GEN is 1), describing number of verses per chapter.
Versification.prototype.books = function () {
return this._books;
};
Versification.prototype.mappings = function () {
return this._verseMappings;
};
Versification.prototype.excludedVerses = function (book, chapter) {
if (!book)
return this._excludedVerses;
if (this._excludedVerses.size === 0)
return this._excludedVerses;
var ret = new Set();
this._excludedVerses.forEach(function (bbbcccvvv) {
if (VerseRef_1.default.toBook(bbbcccvvv) !== book)
return;
if (!chapter || (VerseRef_1.default.toChapter(bbbcccvvv)) === chapter)
ret.add(bbbcccvvv);
});
return ret;
};
Versification.prototype.verseSegments = function (book, chapter) {
var _this = this;
if (!book)
return this._verseSegments;
if (Object.keys(this._verseSegments).length === 0)
return this._verseSegments;
var ret = {};
Object.keys(this._verseSegments).map(Number).forEach(function (bbbcccvvv) {
if (VerseRef_1.default.toBook(bbbcccvvv) !== book)
return;
if (!chapter || (VerseRef_1.default.toChapter(bbbcccvvv) === chapter))
ret[bbbcccvvv] = _this._verseSegments[bbbcccvvv];
});
return ret;
};
// verseRef : The verseRef to find in the verse mappings. (if range will compare first verse in range)
// reverse : if true perform a reverse lookup in the verse mappings.
Versification.prototype.lookupMapping = function (verseRef, reverse) {
var searchIndex = reverse ? 1 : 0;
var resultIndex = reverse ? 0 : 1;
var foundMap = this._verseMappings.find(function (x) { var _a; return ((_a = x[searchIndex]) === null || _a === void 0 ? void 0 : _a.bbbcccvvv()) === verseRef.bbbcccvvv(); });
if (!foundMap)
return undefined;
var result = foundMap[resultIndex];
if (!result)
return undefined;
var diff = result.verseNum() - verseRef.verseNum();
var verseNumEnd = verseRef.verseNumEnd();
return new VerseRef_1.default(result.bbbcccvvv(), verseNumEnd !== undefined ? verseNumEnd + diff : undefined, verseRef.segment(), this);
};
Versification.prototype.changeVersification = function (verseRef) {
if (!verseRef)
return verseRef;
var sourceVersification = verseRef.versification();
if (!sourceVersification)
return new VerseRef_1.default(verseRef.bbbcccvvv(), verseRef.verseNumEnd(), verseRef.segment(), this);
if (sourceVersification.equals(this))
return verseRef;
verseRef = sourceVersification.lookupMapping(verseRef) || verseRef;
verseRef = this.lookupMapping(verseRef, true) || verseRef;
return new VerseRef_1.default(verseRef.bbbcccvvv(), verseRef.verseNumEnd(), verseRef.segment(), this);
};
Versification.prototype.equals = function (versification) {
return this.name === versification.name;
};
return Versification;
}());
exports.default = Versification;