优化链接分割规则,避免 ,{c参数} 的字符串中也存在 ,{ ,导致规则切错

修复<str0,str2,...{{js}}>这种页数列表写法中,js部分内含 < 或 > 就会切割错误的问题

优化格式化图片标签操作和匹配图片标签操作,加快图片处理速度
pull/1118/head
bushixuanqi 3 years ago
parent db3b67567c
commit 2b4242b4d8
  1. 5
      app/src/main/java/io/legado/app/constant/AppPattern.kt
  2. 5
      app/src/main/java/io/legado/app/data/entities/BookChapter.kt
  3. 2
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt
  4. 30
      app/src/main/java/io/legado/app/service/help/ReadBook.kt
  5. 24
      app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt
  6. 29
      app/src/main/java/io/legado/app/utils/HtmlFormatter.kt

@ -8,9 +8,8 @@ object AppPattern {
Pattern.compile("(<js>[\\w\\W]*?</js>|@js:[\\w\\W]*$)", Pattern.CASE_INSENSITIVE) Pattern.compile("(<js>[\\w\\W]*?</js>|@js:[\\w\\W]*$)", Pattern.CASE_INSENSITIVE)
val EXP_PATTERN: Pattern = Pattern.compile("\\{\\{([\\w\\W]*?)\\}\\}") val EXP_PATTERN: Pattern = Pattern.compile("\\{\\{([\\w\\W]*?)\\}\\}")
//非格式化时,不需要原来那么复杂的正则表达式 //只匹配格式化后的图片
val imgPattern: Pattern = val imgPattern: Pattern = Pattern.compile("<img src=\"([^\"{]+(?:\\{(?:[^{}]|\\{[^{}]*\\})*\\})?)\">")
Pattern.compile("<img[^>]*src *= *\"([^\"{]+(?:\\{(?:[^{}]|\\{[^{}]*\\})*\\})?)\"[^>]*>", Pattern.CASE_INSENSITIVE)
val nameRegex = Regex("\\s+作\\s*者.*|\\s+\\S+\\s+著") val nameRegex = Regex("\\s+作\\s*者.*|\\s+\\S+\\s+著")
val authorRegex = Regex("^.*?作\\s*者[::\\s]*|\\s+著") val authorRegex = Regex("^.*?作\\s*者[::\\s]*|\\s+著")

@ -7,6 +7,7 @@ import androidx.room.Ignore
import androidx.room.Index import androidx.room.Index
import io.legado.app.utils.GSON import io.legado.app.utils.GSON
import io.legado.app.utils.MD5Utils import io.legado.app.utils.MD5Utils
import io.legado.app.utils.NetworkUtils
import io.legado.app.utils.fromJsonObject import io.legado.app.utils.fromJsonObject
import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ -60,9 +61,7 @@ data class BookChapter(
return false return false
} }
fun getAbsoluteURL():String{ fun getAbsoluteURL() = url.replace("^\\s*([^,\\s]+)\\s*".toRegex()){ NetworkUtils.getAbsoluteURL(baseUrl,it.groupValues[1]) }
return url.replace("^\\s*([^,\\s]+)".toRex(),NetworkUtils.getAbsoluteURL(baseUrl,"$1"))
}
fun getFileName(): String = String.format("%05d-%s.nb", index, MD5Utils.md5Encode16(title)) fun getFileName(): String = String.format("%05d-%s.nb", index, MD5Utils.md5Encode16(title))

@ -66,7 +66,7 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
fun setRedirectUrl(url: String): URL? { fun setRedirectUrl(url: String): URL? {
kotlin.runCatching { kotlin.runCatching {
val pos = url.indexOf(',') val pos = url.indexOf(',')
redirectUrl = URL( if(pos == -1) url else url.substring(0,pos).trim{ it < '!'} ) redirectUrl = URL( if(pos == -1)url else url.substring(pos+1).trim{ it < '!'} )
} }
return redirectUrl return redirectUrl
} }

@ -415,30 +415,22 @@ object ReadBook {
else -> chapter.title else -> chapter.title
} }
val contents = contentProcessor!!.getContent(book, chapter.title, content) val contents = contentProcessor!!.getContent(book, chapter.title, content)
when (chapter.index) { val textChapter = ChapterProvider.getTextChapter(book, chapter,contents,chapterSize)
durChapterIndex -> {
curTextChapter = val offset = chapter.index - durChapterIndex
ChapterProvider.getTextChapter( if (upContent) callBack?.upContent(offset ,resetPageOffset)
book, chapter, contents, chapterSize when (offset) {
) 0 -> {
if (upContent) callBack?.upContent(resetPageOffset = resetPageOffset) curTextChapter = textChapter
callBack?.upView() callBack?.upView()
curPageChanged() curPageChanged()
callBack?.contentLoadFinish() callBack?.contentLoadFinish()
} }
durChapterIndex - 1 -> { - 1 -> {
prevTextChapter = prevTextChapter = textChapter
ChapterProvider.getTextChapter(
book, chapter, contents, chapterSize
)
if (upContent) callBack?.upContent(-1, resetPageOffset)
} }
durChapterIndex + 1 -> { 1 -> {
nextTextChapter = nextTextChapter = textChapter
ChapterProvider.getTextChapter(
book, chapter, contents, chapterSize
)
if (upContent) callBack?.upContent(1, resetPageOffset)
} }
} }
} }

@ -110,19 +110,11 @@ object ChapterProvider {
isTitle, textPaint, srcList isTitle, textPaint, srcList
) )
} }
} else if (book.getImageStyle() != Book.imgStyleText) { } else {
content.replace(AppPattern.imgPattern.toRegex(), "\n\$0\n") content.replace(AppPattern.imgPattern.toRegex(), "\n\b\$0\n")
.split("\n").forEach { text -> .split("\n").forEach { text ->
if (text.isNotBlank()) { if (text.isNotBlank()) {
val matcher = AppPattern.imgPattern.matcher(text) if(text[0] != '\b'){ //非图片
if (matcher.find()) {
matcher.group(1)?.let { src ->
durY = setTypeImage(
book, bookChapter, src,
durY, textPages, book.getImageStyle()
)
}
} else {
val isTitle = index == 0 val isTitle = index == 0
val textPaint = if (isTitle) titlePaint else contentPaint val textPaint = if (isTitle) titlePaint else contentPaint
if (!(isTitle && ReadBookConfig.titleMode == 2)) { if (!(isTitle && ReadBookConfig.titleMode == 2)) {
@ -131,6 +123,11 @@ object ChapterProvider {
stringBuilder, isTitle, textPaint stringBuilder, isTitle, textPaint
) )
} }
} else { //图片
durY = setTypeImage(
book, bookChapter, text.substring(1),
durY, textPages, book.getImageStyle()
)
} }
} }
} }
@ -149,7 +146,10 @@ object ChapterProvider {
return TextChapter( return TextChapter(
bookChapter.index, bookChapter.title, bookChapter.index, bookChapter.title,
bookChapter.getAbsoluteURL().split(',',limit = 1)[0], //bookChapter.getAbsoluteURL已经处理过,直接按','就行 bookChapter.getAbsoluteURL().run{
val pos = indexOf(',')
if(pos == -1) this else substring(0,pos)
},
textPages, chapterSize textPages, chapterSize
) )
} }

@ -25,31 +25,22 @@ object HtmlFormatter {
val keepImgHtml = formatKeepImg(html) val keepImgHtml = formatKeepImg(html)
val sb = StringBuffer() val sb = StringBuffer()
//图片有data-开头的数据属性时优先用数据属性作为src,没有数据属性时才匹配src //图片有data-开头的数据属性时优先用数据属性作为src,没有数据属性时匹配src
val hasData = keepImgHtml.matches("<img[^>]*data-".toRegex()) val imgPatternX = Pattern.compile(
if(keepImgHtml.matches("<img[^>]*data-".toRegex())) "<img[^>]*data-[^=]*= *\"([^\"])\"[^>]*>"
val imgPatternX = if(hasData) Pattern.compile("<img[^>]*data-[^=]*= *\"([^\"])\"[^>]*>", Pattern.CASE_INSENSITIVE) else imgPattern else "<img[^>]*src *= *\"([^\"{]+(?:\\{(?:[^{}]|\\{[^{}]*\\})*\\})?)\"[^>]*>", Pattern.CASE_INSENSITIVE
)
val matcher = imgPatternX.matcher(keepImgHtml) val matcher = imgPatternX.matcher(keepImgHtml)
var appendPos = 0 var appendPos = 0
while (matcher.find()) { while (matcher.find()) {
var url = matcher.group(1)!!
val param:String
val pos = url.indexOf(',')
url = NetworkUtils.getAbsoluteURL(redirectUrl, if(pos == -1){
param = ""
url.trim{ it <'!'}
} else {
param = url.substring(pos+1).trim{ it <'!'}
url.substring(0,pos).trim{ it <'!'}
})
sb.append(keepImgHtml.substring(appendPos, matcher.start())) sb.append(keepImgHtml.substring(appendPos, matcher.start()))
sb.append("<img src=\"${url+param}\" >") sb.append("<img src=\"${
matcher.group(1)!!.replace("^\\s*([^,\\s]+)\\s*".toRegex()){
NetworkUtils.getAbsoluteURL(redirectUrl,it.groupValues[1])
}
}\">")
appendPos = matcher.end() appendPos = matcher.end()
} }
if (appendPos < keepImgHtml.length) { if (appendPos < keepImgHtml.length) {
sb.append(keepImgHtml.substring(appendPos, keepImgHtml.length)) sb.append(keepImgHtml.substring(appendPos, keepImgHtml.length))

Loading…
Cancel
Save