mirror of
https://gitlab.com/walljm/dynamicbible.git
synced 2025-07-23 07:19:50 -04:00
Snapshot of a couple things.
Fixed some parsing bugs with tests. The beginnings of reference overlap detection.
This commit is contained in:
parent
eb862a580a
commit
f537f515f5
@ -1,6 +1,11 @@
|
||||
import { BibleReference } from './bible-reference';
|
||||
import { BibleReference, Overlap } from './bible-reference';
|
||||
|
||||
describe('Reference', () => {
|
||||
it('Should parse the reference: Gen 1-2', () => {
|
||||
const ref = new BibleReference('Gen 1-2').toString();
|
||||
expect(ref).toBe('Genesis 1:1 - 2:25');
|
||||
});
|
||||
|
||||
it('Should parse the reference: Gen 1:1', () => {
|
||||
const ref = new BibleReference('Gen 1:1').toString();
|
||||
expect(ref).toBe('Genesis 1:1');
|
||||
@ -11,11 +16,6 @@ describe('Reference', () => {
|
||||
expect(ref).toBe('Genesis 1:1 - 11');
|
||||
});
|
||||
|
||||
it('Should parse the reference: Gen 1-2', () => {
|
||||
const ref = new BibleReference('Gen 1-2').toString();
|
||||
expect(ref).toBe('Genesis 1:1 - 2:*');
|
||||
});
|
||||
|
||||
it('Should parse the reference: John 3:16', () => {
|
||||
const ref = new BibleReference('John 3:16').toString();
|
||||
expect(ref).toBe('John 3:16');
|
||||
@ -23,7 +23,7 @@ describe('Reference', () => {
|
||||
|
||||
it('Should parse the reference: John 3-6', () => {
|
||||
const ref = new BibleReference('Jn 3-6').toString();
|
||||
expect(ref).toBe('John 3:1 - 6:*');
|
||||
expect(ref).toBe('John 3:1 - 6:71');
|
||||
});
|
||||
|
||||
it('Should parse the reference: 1 Corinthians 3:5-6:5', () => {
|
||||
@ -266,17 +266,8 @@ describe('Reference', () => {
|
||||
it('Should parse the references: ' + bk.abbr, () => {
|
||||
const book = BibleReference.parseBook(bk.abbr);
|
||||
expect(book.name).toBe(bk.actual);
|
||||
for (let i = 1; i <= book.lastChapter; i++) {
|
||||
expect(new BibleReference(bk.abbr + ' ' + i).toString()).toBe(
|
||||
bk.actual + ' ' + i + ':1 - *'
|
||||
);
|
||||
}
|
||||
|
||||
for (let i = 1; i < book.lastChapter; i++) {
|
||||
expect(
|
||||
new BibleReference(bk.abbr + ' ' + i + '-' + (i + 1)).toString()
|
||||
).toBe(bk.actual + ' ' + i + ':1 - ' + (i + 1) + ':*');
|
||||
|
||||
expect(
|
||||
new BibleReference(
|
||||
bk.abbr + ' ' + i + ':3-' + (i + 1) + ':6'
|
||||
@ -304,3 +295,33 @@ describe('Reference', () => {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('Reference Overlap Detection', () => {
|
||||
// it('Different books dont overlap', () => {
|
||||
// const leftRf = new BibleReference('Gen 1:1-5');
|
||||
// const rightRef = new BibleReference('Exodus 1:3-7');
|
||||
//
|
||||
// expect(BibleReference.overlap(leftRf, rightRef)).toBe(Overlap.None);
|
||||
// });
|
||||
//
|
||||
// it('Different chapters dont overlap', () => {
|
||||
// const leftRef = new BibleReference('Gen 1:1-5');
|
||||
// const rightRef = new BibleReference('Gen 2:1-5');
|
||||
//
|
||||
// expect(BibleReference.overlap(leftRef, rightRef)).toBe(Overlap.None);
|
||||
// });
|
||||
//
|
||||
// it('Detects Left intersects the front of Right', () => {
|
||||
// const leftRef = new BibleReference('Gen 1:1-5');
|
||||
// const rightRef = new BibleReference('Gen 1:4-5');
|
||||
//
|
||||
// expect(BibleReference.overlap(leftRef, rightRef)).toBe(Overlap.Intersect);
|
||||
// });
|
||||
|
||||
it('Detects Right intersects the front of left', () => {
|
||||
const leftRef = new BibleReference('Gen 1:7-10');
|
||||
const rightRef = new BibleReference('Gen 1:5-8');
|
||||
|
||||
expect(BibleReference.overlap(leftRef, rightRef)).toBe(Overlap.Intersect);
|
||||
});
|
||||
});
|
@ -3,6 +3,8 @@
|
||||
// Jason@walljm.com // www.walljm.com
|
||||
// Jeremy@marzhillstudios.com // jeremy.marzhillstudios.com
|
||||
|
||||
import { NONE_TYPE } from '@angular/compiler';
|
||||
|
||||
class StringUtils {
|
||||
public static trim(str: string): string {
|
||||
return str.replace(/^\s+|\s+$/g, '');
|
||||
@ -17,23 +19,29 @@ class StringUtils {
|
||||
}
|
||||
}
|
||||
|
||||
export enum Overlap {
|
||||
Intersect,
|
||||
Subset,
|
||||
None,
|
||||
}
|
||||
|
||||
export class BibleReference {
|
||||
constructor(reference: string) {
|
||||
this.Section = {
|
||||
book: null,
|
||||
start: {
|
||||
chapter: '',
|
||||
verse: '',
|
||||
chapter: 0,
|
||||
verse: 0,
|
||||
},
|
||||
end: {
|
||||
chapter: '',
|
||||
verse: '',
|
||||
chapter: 0,
|
||||
verse: 0,
|
||||
},
|
||||
};
|
||||
this.ref = reference.toLowerCase().trim();
|
||||
this.parseReference();
|
||||
|
||||
if (this.Section.end.chapter === '') {
|
||||
if (this.Section.end.chapter === 0) {
|
||||
this.Section.end.chapter = this.Section.start.chapter;
|
||||
}
|
||||
if (
|
||||
@ -42,11 +50,11 @@ export class BibleReference {
|
||||
) {
|
||||
this.Section.end.verse = this.Section.start.verse;
|
||||
}
|
||||
if (this.Section.start.verse === '') {
|
||||
this.Section.start.verse = '1';
|
||||
if (this.Section.start.verse === 0) {
|
||||
this.Section.start.verse = 1;
|
||||
}
|
||||
if (this.Section.end.verse === '') {
|
||||
this.Section.end.verse = '*';
|
||||
if (this.Section.end.verse === 0) {
|
||||
this.Section.end.verse = this.Section.book.chapters[this.Section.end.chapter];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1866,9 +1874,9 @@ export class BibleReference {
|
||||
// get the starting book, chapter, verse
|
||||
let ref = section.book.name
|
||||
.concat(' ')
|
||||
.concat(section.start.chapter)
|
||||
.concat(section.start.chapter.toString())
|
||||
.concat(':')
|
||||
.concat(section.start.verse);
|
||||
.concat(section.start.verse.toString());
|
||||
|
||||
if (
|
||||
section.start.chapter === section.end.chapter &&
|
||||
@ -1881,14 +1889,14 @@ export class BibleReference {
|
||||
section.start.chapter === section.end.chapter &&
|
||||
section.start.verse !== section.end.verse
|
||||
) {
|
||||
return ref.concat(' - ').concat(section.end.verse);
|
||||
return ref.concat(' - ').concat(section.end.verse.toString());
|
||||
}
|
||||
|
||||
ref = ref.concat(' - ');
|
||||
|
||||
ref = ref.concat(section.end.chapter).concat(':');
|
||||
ref = ref.concat(section.end.chapter.toString()).concat(':');
|
||||
|
||||
return ref.concat(section.end.verse);
|
||||
return ref.concat(section.end.verse.toString());
|
||||
}
|
||||
|
||||
public static bookName(booknum: number): Book {
|
||||
@ -1909,22 +1917,54 @@ export class BibleReference {
|
||||
return new BibleReference(`${book} ${keyArray[1]}:${keyArray[2]}`);
|
||||
}
|
||||
|
||||
public static overlap(leftRef: BibleReference, rightRef: BibleReference): Overlap {
|
||||
if (leftRef.Section.book !== rightRef.Section.book) {
|
||||
// either of the above means we are not overlapping
|
||||
console.log("Not same book");
|
||||
return Overlap.None;
|
||||
}
|
||||
|
||||
if (leftRef.Section.end.chapter === rightRef.Section.start.chapter) {
|
||||
console.log("Same chapter");
|
||||
console.log("Left Section", leftRef.Section);
|
||||
console.log("Right Section", rightRef.Section);
|
||||
if ((leftRef.Section.end.verse > rightRef.Section.start.verse)
|
||||
|| (rightRef.Section.end.verse > leftRef.Section.start.verse)) {
|
||||
console.log("Overlap detected");
|
||||
return Overlap.Intersect;
|
||||
}
|
||||
}
|
||||
console.log("Default case");
|
||||
return Overlap.None;
|
||||
}
|
||||
|
||||
public static mergeReference(ref1: BibleReference, ref2: BibleReference) {
|
||||
// eliminate based on book first.
|
||||
if (ref1.Section.book != ref2.Section.book) {
|
||||
// either of the above mean we are not overlapping
|
||||
return null;
|
||||
}
|
||||
// detect overlaps from end
|
||||
// detect embedded
|
||||
return null;
|
||||
}
|
||||
|
||||
private parseReference() {
|
||||
this.parseKeyReference();
|
||||
if (this.ref.length === 0) {
|
||||
return;
|
||||
}
|
||||
this.parseBook(false);
|
||||
this.parseFirstNum(false);
|
||||
this.parseChapter(false);
|
||||
|
||||
const foundFirstVerse = this.ref.search(/:.*-/) !== -1;
|
||||
this.maybeParseSecondNum(false);
|
||||
this.maybeParseVerse(false);
|
||||
this.maybeParseRangeSep();
|
||||
const foundSecondBook = this.ref.search(/\w\s+\d/i) !== -1;
|
||||
|
||||
this.maybeParseBook(true);
|
||||
this.maybeParseFirstNumOrVerse(foundSecondBook, foundFirstVerse, true);
|
||||
this.maybeParseSecondNum(true);
|
||||
this.maybeParseChapterOrVerse(foundSecondBook, foundFirstVerse, true);
|
||||
this.maybeParseVerse(true);
|
||||
}
|
||||
|
||||
// we're trying to parse references in the form of 41:2:3
|
||||
@ -1937,12 +1977,12 @@ export class BibleReference {
|
||||
this.Section.book = fbook;
|
||||
|
||||
const fch = parts[1];
|
||||
this.Section.end.chapter = fch;
|
||||
this.Section.start.chapter = fch;
|
||||
this.Section.end.chapter = parseInt(fch, 10);
|
||||
this.Section.start.chapter = parseInt(fch, 10);
|
||||
|
||||
const fv = parts[2];
|
||||
this.Section.end.verse = fv;
|
||||
this.Section.start.verse = fv;
|
||||
this.Section.end.verse = parseInt(fv, 10);
|
||||
this.Section.start.verse = parseInt(fv, 10);
|
||||
|
||||
this.ref = '';
|
||||
}
|
||||
@ -1959,7 +1999,7 @@ export class BibleReference {
|
||||
this.Section.book = BibleReference.parseBook(fbook);
|
||||
}
|
||||
|
||||
private parseFirstNum(isEnd: boolean) {
|
||||
private parseChapter(isEnd: boolean) {
|
||||
let thing = this.Section.start;
|
||||
if (isEnd) {
|
||||
thing = this.Section.end;
|
||||
@ -1967,27 +2007,29 @@ export class BibleReference {
|
||||
|
||||
this.ref = StringUtils.ltrim(this.ref);
|
||||
let found = false;
|
||||
let chapter = '';
|
||||
for (let i = 0; i <= this.ref.length; i++) {
|
||||
const c = this.ref.charAt(i);
|
||||
// Grab characters until we hit a non digit.
|
||||
if ('0'.charAt(0) <= c && c <= '9'.charAt(0)) {
|
||||
found = true;
|
||||
thing.chapter = thing.chapter.concat(c);
|
||||
chapter = chapter.concat(c);
|
||||
} else {
|
||||
// if the chapter is longer than 3 digits it's an error
|
||||
if (thing.chapter.length > 3) {
|
||||
this.errAcc = 'Chapter too long"' + thing.chapter + '".';
|
||||
if (chapter.length > 3) {
|
||||
this.errAcc = 'Chapter too long"' + chapter + '".';
|
||||
return;
|
||||
} else if (!found) {
|
||||
this.errAcc = 'No chapter found' + this.ref;
|
||||
}
|
||||
this.ref = this.ref.slice(i);
|
||||
thing.chapter = parseInt(chapter, 10);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private parseSecondNum(skipColon?: boolean, isEnd?: boolean) {
|
||||
private parseVerse(skipColon?: boolean, isEnd?: boolean) {
|
||||
let thing = this.Section.start;
|
||||
if (isEnd) {
|
||||
thing = this.Section.end;
|
||||
@ -2001,21 +2043,23 @@ export class BibleReference {
|
||||
this.ref = this.ref.slice(1);
|
||||
}
|
||||
this.ref = StringUtils.ltrim(this.ref.toLowerCase());
|
||||
let verse = '';
|
||||
if (this.ref[0] === '*') {
|
||||
thing.verse = '*';
|
||||
thing.verse = 0;
|
||||
this.ref = this.ref.slice(1);
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i <= this.ref.length; i++) {
|
||||
const c = this.ref.charAt(i);
|
||||
if ('0'.charAt(0) <= c && c <= '9'.charAt(0)) {
|
||||
thing.verse = thing.verse.concat(c);
|
||||
verse = verse.concat(c);
|
||||
} else {
|
||||
if (thing.verse.length > 3) {
|
||||
if (verse.length > 3) {
|
||||
this.errAcc = 'Verse too long "' + thing.verse + '".';
|
||||
return;
|
||||
}
|
||||
this.ref = this.ref.slice(i);
|
||||
thing.verse = verse === '' ? 0 : parseInt(verse, 10);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2029,13 +2073,13 @@ export class BibleReference {
|
||||
});
|
||||
}
|
||||
|
||||
private maybeParseSecondNum(isEnd?: boolean) {
|
||||
private maybeParseVerse(isEnd?: boolean) {
|
||||
return this.maybeDo(() => {
|
||||
this.parseSecondNum(false, isEnd);
|
||||
this.parseVerse(false, isEnd);
|
||||
});
|
||||
}
|
||||
|
||||
private maybeParseFirstNumOrVerse(
|
||||
private maybeParseChapterOrVerse(
|
||||
foundSecondBook: boolean,
|
||||
foundFirstVerse: boolean,
|
||||
isEnd: boolean
|
||||
@ -2043,9 +2087,9 @@ export class BibleReference {
|
||||
const self = this;
|
||||
return this.maybeDo(() => {
|
||||
if (self.ref.search(/:/) !== -1 || foundSecondBook || !foundFirstVerse) {
|
||||
self.parseFirstNum(isEnd);
|
||||
self.parseChapter(isEnd);
|
||||
}
|
||||
self.parseSecondNum(true, isEnd);
|
||||
self.parseVerse(true, isEnd);
|
||||
});
|
||||
}
|
||||
|
||||
@ -2088,6 +2132,6 @@ export interface Section {
|
||||
}
|
||||
|
||||
export interface Location {
|
||||
chapter: string;
|
||||
verse: string;
|
||||
chapter: number;
|
||||
verse: number;
|
||||
}
|
||||
|
@ -74,52 +74,52 @@ const initialState: AppState = {
|
||||
|
||||
type AppAction =
|
||||
| {
|
||||
type: 'GET_SAVED_PAGE';
|
||||
pageId: string;
|
||||
}
|
||||
type: 'GET_SAVED_PAGE';
|
||||
pageId: string;
|
||||
}
|
||||
| {
|
||||
type: 'UPDATE_SAVED_PAGES';
|
||||
savedPages: SavedPage[];
|
||||
}
|
||||
type: 'UPDATE_SAVED_PAGES';
|
||||
savedPages: SavedPage[];
|
||||
}
|
||||
| {
|
||||
type: 'ADD_CARD_TO_SAVED_PAGE';
|
||||
card: CardItem;
|
||||
pageId: string;
|
||||
}
|
||||
type: 'ADD_CARD_TO_SAVED_PAGE';
|
||||
card: CardItem;
|
||||
pageId: string;
|
||||
}
|
||||
| {
|
||||
type: 'ADD_CARD';
|
||||
card: CardItem;
|
||||
nextToItem: CardItem;
|
||||
}
|
||||
type: 'ADD_CARD';
|
||||
card: CardItem;
|
||||
nextToItem: CardItem;
|
||||
}
|
||||
| {
|
||||
type: 'UPDATE_CARD';
|
||||
newCard: CardItem;
|
||||
oldCard: CardItem;
|
||||
}
|
||||
type: 'UPDATE_CARD';
|
||||
newCard: CardItem;
|
||||
oldCard: CardItem;
|
||||
}
|
||||
| {
|
||||
type: 'REMOVE_CARD';
|
||||
card: CardItem;
|
||||
}
|
||||
type: 'REMOVE_CARD';
|
||||
card: CardItem;
|
||||
}
|
||||
| {
|
||||
type: 'UPDATE_ERROR';
|
||||
error: Error;
|
||||
}
|
||||
type: 'UPDATE_ERROR';
|
||||
error: Error;
|
||||
}
|
||||
| {
|
||||
type: 'UPDATE_FONT_SIZE';
|
||||
size: number;
|
||||
}
|
||||
type: 'UPDATE_FONT_SIZE';
|
||||
size: number;
|
||||
}
|
||||
| {
|
||||
type: 'UPDATE_FONT_FAMILY';
|
||||
cardFont: string;
|
||||
}
|
||||
type: 'UPDATE_FONT_FAMILY';
|
||||
cardFont: string;
|
||||
}
|
||||
| {
|
||||
type: 'UPDATE_AUTOCOMPLETE';
|
||||
words: string[];
|
||||
}
|
||||
type: 'UPDATE_AUTOCOMPLETE';
|
||||
words: string[];
|
||||
}
|
||||
| {
|
||||
type: 'UPDATE_DISPLAY_SETTINGS';
|
||||
settings: DisplaySettings;
|
||||
};
|
||||
type: 'UPDATE_DISPLAY_SETTINGS';
|
||||
settings: DisplaySettings;
|
||||
};
|
||||
|
||||
function reducer(state: AppState, action: AppAction): AppState {
|
||||
// somtimes the state is null. lets not complain if that happens.
|
||||
@ -762,17 +762,7 @@ export class AppService extends createStateService(reducer, initialState) {
|
||||
|
||||
// figure out the start verse.
|
||||
if (j === 0) {
|
||||
if (section.start.verse.indexOf('*') !== -1) {
|
||||
// you sometimes use this as a shortcut to the last verse
|
||||
// replace the * with the last verse
|
||||
// e.g jn 1:* - 3:4
|
||||
|
||||
// update the section and the ref.
|
||||
section.start.verse = chapters[j].vss.length.toString();
|
||||
result.ref = BibleReference.toString(section);
|
||||
} else {
|
||||
start = parseInt(section.start.verse, 10);
|
||||
}
|
||||
start = section.start.verse;
|
||||
} else {
|
||||
start = 1;
|
||||
}
|
||||
@ -786,7 +776,7 @@ export class AppService extends createStateService(reducer, initialState) {
|
||||
|
||||
// get the verses requested.
|
||||
const tvs = chapters[j].vss.length;
|
||||
if (end === '*' || parseInt(end, 10) > tvs) {
|
||||
if (end === '*' || end > tvs) {
|
||||
end = tvs;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user