Files
vorleser/VorleserKit/Sources/BookParser/Book.swift

53 lines
1.5 KiB
Swift

import Foundation
import VorleserKit
public struct Book: Sendable {
public let id: UUID
public let title: String
public let author: String?
public let chapters: [Chapter]
public init(id: UUID = UUID(), title: String, author: String?, chapters: [Chapter]) {
self.id = id
self.title = title
self.author = author
self.chapters = chapters
}
/// All sentences across all chapters, with global character offsets.
public var sentences: [Sentence] {
var result: [Sentence] = []
var offset: CharacterOffset = 0
for chapter in chapters {
let chapterSentences = SentenceSegmenter.segment(chapter.text, globalOffset: offset)
result.append(contentsOf: chapterSentences)
offset += chapter.text.count
}
return result
}
/// Returns the sentence index containing the given global character offset.
public func sentenceIndex(containing offset: CharacterOffset) -> Int? {
let allSentences = sentences
return allSentences.firstIndex { $0.range.contains(offset) }
}
/// Maps a global character offset to (chapter index, local offset within chapter).
public func chapterAndLocalOffset(for globalOffset: CharacterOffset) -> (chapterIndex: Int, localOffset: Int)? {
var offset = 0
for chapter in chapters {
let chapterEnd = offset + chapter.text.count
if globalOffset < chapterEnd {
return (chapter.index, globalOffset - offset)
}
offset = chapterEnd
}
return nil
}
/// Total character count across all chapters.
public var totalCharacters: Int {
chapters.reduce(0) { $0 + $1.text.count }
}
}