This commit is contained in:
Horis 2024-12-08 20:49:57 +08:00
parent 67d0462581
commit 20ab778ec0
3 changed files with 58 additions and 19 deletions

View File

@ -109,14 +109,11 @@ object LocalBook {
throw TocEmptyException(appCtx.getString(R.string.chapter_list_empty))
}
val list = ArrayList(LinkedHashSet(chapters))
var wordCount = 0
list.forEachIndexed { index, bookChapter ->
bookChapter.index = index
wordCount += bookChapter.tag?.toInt() ?: 0
}
book.latestChapterTitle = list.last().title
book.totalChapterNum = list.size
book.wordCount = wordCount.toString() + ""
book.save()
return list
}

View File

@ -90,7 +90,8 @@ class TextFile(private var book: Book) {
}
}
}
val toc = analyze(book.tocUrl.toPattern(Pattern.MULTILINE))
val (toc, wordCount) = analyze(book.tocUrl.toPattern(Pattern.MULTILINE))
book.wordCount = StringUtils.wordCountFormat(wordCount)
toc.forEachIndexed { index, bookChapter ->
bookChapter.index = index
bookChapter.bookUrl = book.bookUrl
@ -140,18 +141,19 @@ class TextFile(private var book: Book) {
/**
* 按规则解析目录
*/
private fun analyze(pattern: Pattern?): ArrayList<BookChapter> {
private fun analyze(pattern: Pattern?): Pair<ArrayList<BookChapter>, Int> {
if (pattern?.pattern().isNullOrEmpty()) {
return analyze()
}
pattern ?: return analyze()
val toc = arrayListOf<BookChapter>()
var bookWordCount = 0
LocalBook.getBookInputStream(book).use { bis ->
var blockContent: String
//加载章节
var curOffset: Long = 0
//读取的长度
var length: Int
var lastChapterWordCount = 0
val buffer = ByteArray(bufferSize)
var bufferStart = 3
bis.read(buffer, 0, 3)
@ -192,11 +194,12 @@ class TextFile(private var book: Book) {
if (book.getSplitLongChapter() && curOffset + chapterLength - lastStart > maxLengthWithToc) {
toc.lastOrNull()?.let {
it.end = it.start
it.tag = null
}
//章节字数太多进行拆分
val lastTitle = toc.lastOrNull()?.title
val lastTitleLength = lastTitle?.toByteArray(charset)?.size ?: 0
val chapters = analyze(
val (chapters, wordCount) = analyze(
lastStart + lastTitleLength, curOffset + chapterLength
)
lastTitle?.let {
@ -205,6 +208,7 @@ class TextFile(private var book: Book) {
}
}
toc.addAll(chapters)
bookWordCount += wordCount
//创建当前章节
val curChapter = BookChapter()
curChapter.title = matcher.group()
@ -222,7 +226,7 @@ class TextFile(private var book: Book) {
qyChapter.title = "前言"
qyChapter.start = curOffset
qyChapter.end = curOffset + chapterLength
qyChapter.tag = chapterContent.length.toString()
qyChapter.tag = StringUtils.wordCountFormat(chapterContent.length)
toc.add(qyChapter)
book.intro = if (chapterContent.length <= 500) {
chapterContent
@ -242,13 +246,16 @@ class TextFile(private var book: Book) {
chapterContent.substringAfter(lastChapter.title).isBlank()
//将当前段落添加上一章去
lastChapter.end = lastChapter.end!! + chapterLength
lastChapter.tag = ((lastChapter.tag?.toInt() ?: 0) + chapterContent.length).toString()
lastChapterWordCount += chapterContent.length
lastChapter.tag = StringUtils.wordCountFormat(lastChapterWordCount)
//创建当前章节
val curChapter = BookChapter()
curChapter.title = matcher.group()
curChapter.start = lastChapter.end
toc.add(curChapter)
}
bookWordCount += chapterContent.length
lastChapterWordCount = 0
} else {
if (toc.isNotEmpty()) { //获取章节内容
//获取上一章节
@ -257,7 +264,7 @@ class TextFile(private var book: Book) {
chapterContent.substringAfter(lastChapter.title).isBlank()
lastChapter.end =
lastChapter.start!! + chapterLength
lastChapter.tag = chapterContent.length.toString()
lastChapter.tag = StringUtils.wordCountFormat(chapterContent.length)
//创建当前章节
val curChapter = BookChapter()
curChapter.title = matcher.group()
@ -268,19 +275,24 @@ class TextFile(private var book: Book) {
curChapter.title = matcher.group()
curChapter.start = curOffset
curChapter.end = curOffset
curChapter.tag = chapterContent.length.toString()
curChapter.tag = StringUtils.wordCountFormat(chapterContent.length)
toc.add(curChapter)
}
bookWordCount += chapterContent.length
lastChapterWordCount = 0
}
//设置指针偏移
seekPos += chapterContent.length
}
val wordCount = blockContent.length - seekPos
bookWordCount += wordCount
lastChapterWordCount += wordCount
//block的偏移点
curOffset += length.toLong()
//设置上一章的结尾
toc.lastOrNull()?.let {
it.end = curOffset
it.tag = blockContent.substring(seekPos).length.toString()
it.tag = StringUtils.wordCountFormat(lastChapterWordCount)
}
}
toc.lastOrNull()?.let { chapter ->
@ -288,9 +300,10 @@ class TextFile(private var book: Book) {
if (book.getSplitLongChapter() && chapter.end!! - chapter.start!! > maxLengthWithToc) {
val end = chapter.end!!
chapter.end = chapter.start
chapter.tag = null
val lastTitle = chapter.title
val lastTitleLength = lastTitle.toByteArray(charset).size
val chapters = analyze(
val (chapters, _) = analyze(
chapter.start!! + lastTitleLength, end
)
chapters.forEachIndexed { index, bookChapter ->
@ -302,7 +315,7 @@ class TextFile(private var book: Book) {
}
System.gc()
System.runFinalization()
return toc
return toc to bookWordCount
}
/**
@ -310,8 +323,9 @@ class TextFile(private var book: Book) {
*/
private fun analyze(
fileStart: Long = 0L, fileEnd: Long = Long.MAX_VALUE
): ArrayList<BookChapter> {
): Pair<ArrayList<BookChapter>, Int> {
val toc = arrayListOf<BookChapter>()
var bookWordCount = 0
LocalBook.getBookInputStream(book).use { bis ->
//block的个数
var blockPos = 0
@ -320,6 +334,7 @@ class TextFile(private var book: Book) {
var chapterPos = 0
//读取的长度
var length = 0
var lastChapterWordCount = 0
val buffer = ByteArray(bufferSize)
var bufferStart = 3
if (fileStart == 0L) {
@ -360,10 +375,14 @@ class TextFile(private var book: Book) {
break
}
}
val content = String(buffer, chapterOffset, end - chapterOffset, charset)
bookWordCount += content.length
lastChapterWordCount = content.length
val chapter = BookChapter()
chapter.title = "${blockPos}章($chapterPos)"
chapter.start = toc.lastOrNull()?.end ?: curOffset
chapter.end = chapter.start!! + end - chapterOffset
chapter.tag = StringUtils.wordCountFormat(content.length)
toc.add(chapter)
//减去已经被分配的长度
strLength -= (end - chapterOffset)
@ -380,19 +399,24 @@ class TextFile(private var book: Book) {
curOffset += length.toLong()
}
//设置结尾章节
val content = String(buffer, 0, bufferStart, charset)
bookWordCount += content.length
if (bufferStart > 100 || toc.isEmpty()) {
val chapter = BookChapter()
chapter.title = "${blockPos}章(${chapterPos})"
chapter.start = toc.lastOrNull()?.end ?: curOffset
chapter.end = chapter.start!! + bufferStart
chapter.tag = StringUtils.wordCountFormat(content.length)
toc.add(chapter)
} else {
val wordCount = lastChapterWordCount + content.length
toc.lastOrNull()?.let {
it.end = it.end!! + bufferStart
it.tag = StringUtils.wordCountFormat(wordCount)
}
}
}
return toc
return toc to bookWordCount
}
/**

View File

@ -8,7 +8,8 @@ import java.io.ByteArrayOutputStream
import java.io.IOException
import java.text.DecimalFormat
import java.text.SimpleDateFormat
import java.util.*
import java.util.Calendar
import java.util.Locale
import java.util.regex.Matcher
import java.util.regex.Pattern
import java.util.zip.GZIPInputStream
@ -22,6 +23,9 @@ object StringUtils {
private const val DAY_OF_YESTERDAY = 2
private const val TIME_UNIT = 60
private val ChnMap = chnMap
private val wordCountFormatter by lazy {
DecimalFormat("#.#")
}
private val chnMap: HashMap<Char, Int>
get() {
@ -232,16 +236,30 @@ object StringUtils {
return isNum.matches()
}
fun wordCountFormat(words: Int): String {
var wordsS = ""
if (words > 0) {
if (words > 10000) {
val df = wordCountFormatter
wordsS = df.format(words * 1.0f / 10000f.toDouble()) + "万字"
} else {
wordsS = words.toString() + ""
}
}
return wordsS
}
fun wordCountFormat(wc: String?): String {
if (wc == null) return ""
var wordsS = ""
if (isNumeric(wc)) {
val words: Int = wc.toInt()
if (words > 0) {
wordsS = words.toString() + ""
if (words > 10000) {
val df = DecimalFormat("#.#")
val df = wordCountFormatter
wordsS = df.format(words * 1.0f / 10000f.toDouble()) + "万字"
} else {
wordsS = words.toString() + ""
}
}
} else {