From ef24a4d036aa39cbdbfc9f8599a8f72b10e3a78b Mon Sep 17 00:00:00 2001 From: bushixuanqi <2208877960@qq.com> Date: Sun, 18 Jul 2021 17:47:48 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../legado/app/data/entities/BookChapter.kt | 6 +- .../app/model/analyzeRule/AnalyzeRule.kt | 3 +- .../app/model/analyzeRule/AnalyzeUrl.kt | 10 ++- .../read/page/provider/ChapterProvider.kt | 2 +- .../java/io/legado/app/utils/HtmlFormatter.kt | 84 +++++++++++++------ 5 files changed, 72 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/io/legado/app/data/entities/BookChapter.kt b/app/src/main/java/io/legado/app/data/entities/BookChapter.kt index c6b4cb9fb..9d2ecf29c 100644 --- a/app/src/main/java/io/legado/app/data/entities/BookChapter.kt +++ b/app/src/main/java/io/legado/app/data/entities/BookChapter.kt @@ -5,6 +5,7 @@ import androidx.room.Entity import androidx.room.ForeignKey import androidx.room.Ignore import androidx.room.Index +import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.utils.GSON import io.legado.app.utils.MD5Utils import io.legado.app.utils.NetworkUtils @@ -62,9 +63,10 @@ data class BookChapter( } fun getAbsoluteURL():String{ - val urlBefore = url.substringBefore(',') + val urlMatcher = AnalyzeUrl.paramPattern.matcher(url) + val urlBefore = if(urlMatcher.find())url.substring(0,urlMatcher.start()) else url val urlAbsoluteBefore = NetworkUtils.getAbsoluteURL(baseUrl,urlBefore) - return if(urlBefore.length == url.length) urlAbsoluteBefore else urlAbsoluteBefore + url.substring(urlBefore.length) + return if(urlBefore.length == url.length) urlAbsoluteBefore else urlAbsoluteBefore + url.substring(urlMatcher.end()) } fun getFileName(): String = String.format("%05d-%s.nb", index, MD5Utils.md5Encode16(title)) diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt index 1ad285563..948d33471 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt @@ -65,7 +65,8 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions { fun setRedirectUrl(url: String): URL? { kotlin.runCatching { - redirectUrl = URL(url.substringBefore(',')) + val urlMatcher = AnalyzeUrl.paramPattern.matcher(url) + redirectUrl = URL( if(urlMatcher.find())url.substring(0,urlMatcher.start()) else url) } return redirectUrl } diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index 90b4be570..8bbf271ed 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -39,6 +39,7 @@ class AnalyzeUrl( headerMapF: Map? = null ) : JsExtensions { companion object { + val paramPattern = Pattern.compile("\\s*,\\s*(?=\\{)") private val pagePattern = Pattern.compile("<(.*?)>") } @@ -55,7 +56,8 @@ class AnalyzeUrl( private var retry: Int = 0 init { - baseUrl = baseUrl.substringBefore(',') + val urlMatcher = paramPattern.matcher(baseUrl) + if(urlMatcher.find())baseUrl = baseUrl.substring(0,urlMatcher.start()) headerMapF?.let { headerMap.putAll(it) if (it.containsKey("proxy")) { @@ -142,14 +144,14 @@ class AnalyzeUrl( */ private fun initUrl() { //replaceKeyPageJs已经替换掉额外内容,此处url是基础形式,可以直接切首个‘,’之前字符串。 - urlHasQuery = ruleUrl.substringBefore(',') + val urlMatcher = paramPattern.matcher(ruleUrl) + urlHasQuery = if(urlMatcher.find())ruleUrl.substring(0,urlMatcher.start()) else ruleUrl url = NetworkUtils.getAbsoluteURL(baseUrl,urlHasQuery ) NetworkUtils.getBaseUrl(url)?.let { baseUrl = it } - if(urlHasQuery.length != ruleUrl.length ) { - GSON.fromJsonObject(ruleUrl.substring(urlHasQuery.length + 1).trim{ it < '!'})?.let { option -> + GSON.fromJsonObject(ruleUrl.substring(urlMatcher.end()))?.let { option -> option.method?.let { if (it.equals("POST", true)) method = RequestMethod.POST diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt index c3bbf8b6e..d25325a60 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt @@ -146,7 +146,7 @@ object ChapterProvider { return TextChapter( bookChapter.index, bookChapter.title, - bookChapter.getAbsoluteURL().substringBefore(','), + bookChapter.getAbsoluteURL().substringBefore(",{"), //getAbsoluteURL已经格式过 textPages, chapterSize ) } diff --git a/app/src/main/java/io/legado/app/utils/HtmlFormatter.kt b/app/src/main/java/io/legado/app/utils/HtmlFormatter.kt index c02ce2f3d..b05b7093a 100644 --- a/app/src/main/java/io/legado/app/utils/HtmlFormatter.kt +++ b/app/src/main/java/io/legado/app/utils/HtmlFormatter.kt @@ -1,5 +1,6 @@ package io.legado.app.utils +import io.legado.app.model.analyzeRule.AnalyzeUrl import java.net.URL import java.util.regex.Pattern @@ -26,35 +27,68 @@ object HtmlFormatter { .replace("[\\n\\s]+\$|^[\\n\\s]+".toRegex(), "") .replace("\\s*\\n+\\s*".toRegex(), "\n") - val sb = StringBuffer() + var str = "" var endPos = 0 - for(pattern in listOf("]*src *= *\"([^\"{]+(?:\\{(?:[^{}]|\\{[^{}]*\\})*\\})?)\"[^>]*>","]*data-[^=]*= *\"([^\"])\"[^>]*>")){ + var hasMatch = true //普通图片标签是否还未处理过 + var hasMatchX = false //是否存在带参数或带数据属性的图片标签 + var pos = -1 + val list = listOf("]*src *= *\"([^\"{]+\\{(?:[^{}]|\\{[^}]+})+})\"[^>]*>","]*data-[^=]*= *\"([^\"]+)\"[^>]*>","]*src *= *\"([^\"]+)\"[^>]*>") //优先匹配用户处理过所以带参数的图片标签,其次匹配带数据属性的图片标签 + while(++pos<3){ + if(pos == 2) { + if(hasMatchX)break //普通图片标签只在不存在存在带参数或带数据属性的图片标签的时候匹配 + else hasMatch = false //匹配带参数或带数据属性的图片标签同时也会格式化普通图片标签 + } var appendPos = 0 - val matcher = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE).matcher(keepImgHtml) - while (matcher.find()) { - val url = matcher.group(1)!! - val urlBefore = url.substringBefore(',') - val strBefore = keepImgHtml.substring(appendPos, matcher.start()) - sb.append( - if(strBefore.isBlank()) strBefore else strBefore.replace("\n", "\n  ") //缩进图片之间的非空白段落 - ) - sb.append( - "" - ) - appendPos = matcher.end() + val matcher = + Pattern.compile(list[pos], Pattern.CASE_INSENSITIVE).matcher(keepImgHtml) + val sb = StringBuffer() + if (matcher.find()) { + do { + var strBefore = keepImgHtml.substring(appendPos, matcher.start()) + + if (hasMatch) { //格式化不带参数和数据属性的普通图片标签 + var appendPos0 = 0 + val matcher0 = Pattern.compile("]*src *= *\"([^\"]+)\"[^>]*>", Pattern.CASE_INSENSITIVE).matcher(strBefore) //格式化普通图片标签 + while (matcher0.find()) { + val strBefore0 = strBefore.substring(appendPos, matcher.start()) + sb.append( if (strBefore0.isBlank()) strBefore0 else strBefore0.replace("\n","\n  ")) + sb.append("") + appendPos0 = matcher.end() + } + strBefore = if (appendPos0 < strBefore.length) { + strBefore.substring(appendPos0, strBefore.length).replace("\n", "\n  ") //缩进图片之后的非空白段落 + } else "" + } + + sb.append( + if (strBefore.isBlank()) strBefore else strBefore.replace("\n","\n  ") //缩进图片之间的非空白段落 + ) + + if (pos == 0) { + val url = matcher.group(1)!! + val urlMatcher = AnalyzeUrl.paramPattern.matcher(url) + val find = urlMatcher.find() + sb.append("") + + } else sb.append("") + + appendPos = matcher.end() + } while (matcher.find()) + hasMatch = false //普通图片标签已经处理过 } - if(appendPos != 0)endPos = appendPos - } - if (endPos < keepImgHtml.length) { - sb.append( keepImgHtml.substring( endPos, keepImgHtml.length ).replace("\n","\n  ") ) //缩进图片之后的非空白段落 + if (appendPos != 0) { + hasMatchX = true //存在带参数或带数据属性的图片标签 + endPos = appendPos //存在匹配,更新位置 + str = sb.toString() //存在匹配,更新字符串 + } } - return sb.toString() - } + return if (endPos < keepImgHtml.length) { + str + keepImgHtml.substring( endPos, keepImgHtml.length ).replace("\n","\n  ") //缩进图片之后的非空白段落 + }else str + } }