|
@@ -16,6 +16,28 @@ import java.util.regex.Pattern
|
|
|
|
|
|
|
|
class TextFile(private val book: Book) {
|
|
class TextFile(private val book: Book) {
|
|
|
|
|
|
|
|
|
|
+ companion object {
|
|
|
|
|
+
|
|
|
|
|
+ @Throws(FileNotFoundException::class)
|
|
|
|
|
+ fun getChapterList(book: Book): ArrayList<BookChapter> {
|
|
|
|
|
+ return TextFile(book).getChapterList()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Throws(FileNotFoundException::class)
|
|
|
|
|
+ fun getContent(book: Book, bookChapter: BookChapter): String {
|
|
|
|
|
+ val count = (bookChapter.end!! - bookChapter.start!!).toInt()
|
|
|
|
|
+ val buffer = ByteArray(count)
|
|
|
|
|
+ LocalBook.getBookInputStream(book).use { bis ->
|
|
|
|
|
+ bis.skip(bookChapter.start!!)
|
|
|
|
|
+ bis.read(buffer)
|
|
|
|
|
+ }
|
|
|
|
|
+ return String(buffer, book.fileCharset())
|
|
|
|
|
+ .substringAfter(bookChapter.title)
|
|
|
|
|
+ .replace("^[\\n\\s]+".toRegex(), " ")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private val blank: Byte = 0x0a
|
|
private val blank: Byte = 0x0a
|
|
|
|
|
|
|
|
//默认从文件中获取数据的长度
|
|
//默认从文件中获取数据的长度
|
|
@@ -24,7 +46,7 @@ class TextFile(private val book: Book) {
|
|
|
//没有标题的时候,每个章节的最大长度
|
|
//没有标题的时候,每个章节的最大长度
|
|
|
private val maxLengthWithNoToc = 10 * 1024
|
|
private val maxLengthWithNoToc = 10 * 1024
|
|
|
|
|
|
|
|
- private val tocRules = arrayListOf<TxtTocRule>()
|
|
|
|
|
|
|
+ private val tocRules = arrayListOf<Pattern>()
|
|
|
private var charset: Charset = book.fileCharset()
|
|
private var charset: Charset = book.fileCharset()
|
|
|
|
|
|
|
|
@Throws(FileNotFoundException::class)
|
|
@Throws(FileNotFoundException::class)
|
|
@@ -45,7 +67,7 @@ class TextFile(private val book: Book) {
|
|
|
book.charset = EncodingDetect.getEncode(buffer)
|
|
book.charset = EncodingDetect.getEncode(buffer)
|
|
|
blockContent = String(buffer, 0, length, charset)
|
|
blockContent = String(buffer, 0, length, charset)
|
|
|
}
|
|
}
|
|
|
- getTocRule(blockContent)?.rule?.toPattern(Pattern.MULTILINE)
|
|
|
|
|
|
|
+ getTocRule(blockContent)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
@@ -183,9 +205,8 @@ class TextFile(private val book: Book) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private fun analyze(): ArrayList<BookChapter> {
|
|
private fun analyze(): ArrayList<BookChapter> {
|
|
|
- tocRules.removeFirstOrNull()
|
|
|
|
|
- tocRules.firstOrNull()?.let {
|
|
|
|
|
- return analyze(it.rule.toPattern(Pattern.MULTILINE))
|
|
|
|
|
|
|
+ nextTocRule()?.let {
|
|
|
|
|
+ return analyze(it)
|
|
|
}
|
|
}
|
|
|
val toc = arrayListOf<BookChapter>()
|
|
val toc = arrayListOf<BookChapter>()
|
|
|
LocalBook.getBookInputStream(book).use { bis ->
|
|
LocalBook.getBookInputStream(book).use { bis ->
|
|
@@ -266,13 +287,24 @@ class TextFile(private val book: Book) {
|
|
|
return toc
|
|
return toc
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * 获取匹配次数最多的目录规则
|
|
|
|
|
- */
|
|
|
|
|
- private fun getTocRule(content: String): TxtTocRule? {
|
|
|
|
|
- tocRules.clear()
|
|
|
|
|
- val rules = getTocRules().reversed()
|
|
|
|
|
- var txtTocRule: TxtTocRule? = null
|
|
|
|
|
|
|
+ private fun getTocRule(content: String): Pattern? {
|
|
|
|
|
+ tocRules.addAll(getTocRules(content, true))
|
|
|
|
|
+ tocRules.addAll(getTocRules(content, false))
|
|
|
|
|
+ return tocRules.firstOrNull()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private fun nextTocRule(): Pattern? {
|
|
|
|
|
+ tocRules.removeFirstOrNull()
|
|
|
|
|
+ return tocRules.firstOrNull()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private fun getTocRules(content: String, isMain: Boolean): ArrayList<Pattern> {
|
|
|
|
|
+ val list = arrayListOf<Pattern>()
|
|
|
|
|
+ val rules = if (isMain) {
|
|
|
|
|
+ getTocRules().reversed()
|
|
|
|
|
+ } else {
|
|
|
|
|
+ appDb.txtTocRuleDao.disabled.reversed()
|
|
|
|
|
+ }
|
|
|
var maxCs = 0
|
|
var maxCs = 0
|
|
|
for (tocRule in rules) {
|
|
for (tocRule in rules) {
|
|
|
val pattern = Pattern.compile(tocRule.rule, Pattern.MULTILINE)
|
|
val pattern = Pattern.compile(tocRule.rule, Pattern.MULTILINE)
|
|
@@ -282,48 +314,25 @@ class TextFile(private val book: Book) {
|
|
|
cs++
|
|
cs++
|
|
|
}
|
|
}
|
|
|
if (cs >= maxCs) {
|
|
if (cs >= maxCs) {
|
|
|
- tocRules.add(0, tocRule)
|
|
|
|
|
maxCs = cs
|
|
maxCs = cs
|
|
|
- txtTocRule = tocRule
|
|
|
|
|
|
|
+ list.add(0, pattern)
|
|
|
} else if (cs > 0) {
|
|
} else if (cs > 0) {
|
|
|
- tocRules.add(tocRule)
|
|
|
|
|
|
|
+ list.add(pattern)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- return txtTocRule
|
|
|
|
|
|
|
+ return list
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- companion object {
|
|
|
|
|
-
|
|
|
|
|
- @Throws(FileNotFoundException::class)
|
|
|
|
|
- fun getChapterList(book: Book): ArrayList<BookChapter> {
|
|
|
|
|
- return TextFile(book).getChapterList()
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Throws(FileNotFoundException::class)
|
|
|
|
|
- fun getContent(book: Book, bookChapter: BookChapter): String {
|
|
|
|
|
- val count = (bookChapter.end!! - bookChapter.start!!).toInt()
|
|
|
|
|
- val buffer = ByteArray(count)
|
|
|
|
|
- LocalBook.getBookInputStream(book).use { bis ->
|
|
|
|
|
- bis.skip(bookChapter.start!!)
|
|
|
|
|
- bis.read(buffer)
|
|
|
|
|
- }
|
|
|
|
|
- return String(buffer, book.fileCharset())
|
|
|
|
|
- .substringAfter(bookChapter.title)
|
|
|
|
|
- .replace("^[\\n\\s]+".toRegex(), " ")
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private fun getTocRules(): List<TxtTocRule> {
|
|
|
|
|
- var rules = appDb.txtTocRuleDao.enabled
|
|
|
|
|
- if (rules.isEmpty()) {
|
|
|
|
|
- rules = DefaultData.txtTocRules.apply {
|
|
|
|
|
- appDb.txtTocRuleDao.insert(*this.toTypedArray())
|
|
|
|
|
- }.filter {
|
|
|
|
|
- it.enable
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ private fun getTocRules(): List<TxtTocRule> {
|
|
|
|
|
+ var rules = appDb.txtTocRuleDao.enabled
|
|
|
|
|
+ if (rules.isEmpty()) {
|
|
|
|
|
+ rules = DefaultData.txtTocRules.apply {
|
|
|
|
|
+ appDb.txtTocRuleDao.insert(*this.toTypedArray())
|
|
|
|
|
+ }.filter {
|
|
|
|
|
+ it.enable
|
|
|
}
|
|
}
|
|
|
- return rules
|
|
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+ return rules
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|