格式化代码

pull/1128/head^2
gedoor 3 years ago
parent a7b2ae3605
commit 68e9ade4ac
  1. 4
      app/src/main/java/io/legado/app/data/entities/BookChapter.kt
  2. 72
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt
  3. 3
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt
  4. 59
      app/src/main/java/io/legado/app/model/analyzeRule/RuleAnalyzer.kt
  5. 3
      app/src/main/java/io/legado/app/service/help/ReadBook.kt
  6. 14
      app/src/main/java/io/legado/app/utils/HtmlFormatter.kt

@ -64,7 +64,9 @@ data class BookChapter(
fun getAbsoluteURL(): String { fun getAbsoluteURL(): String {
val urlBefore = url.substringBefore(',') val urlBefore = url.substringBefore(',')
val urlAbsoluteBefore = NetworkUtils.getAbsoluteURL(baseUrl, urlBefore) 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(
urlBefore.length
)
} }
fun getFileName(): String = String.format("%05d-%s.nb", index, MD5Utils.md5Encode16(title)) fun getFileName(): String = String.format("%05d-%s.nb", index, MD5Utils.md5Encode16(title))

@ -359,48 +359,21 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
fun splitSourceRule(ruleStr: String?, isList: Boolean = false): List<SourceRule> { fun splitSourceRule(ruleStr: String?, isList: Boolean = false): List<SourceRule> {
if (ruleStr.isNullOrEmpty()) return ArrayList<SourceRule>() if (ruleStr.isNullOrEmpty()) return ArrayList<SourceRule>()
val ruleList = ArrayList<SourceRule>() val ruleList = ArrayList<SourceRule>()
//检测Mode
var mMode: Mode = Mode.Default var mMode: Mode = Mode.Default
fun mode(ruleStr0:String)=when { var start = 0
ruleStr0.startsWith("@@") -> { //仅首字符为:时为AllInOne,其实:与伪类选择器冲突,建议改成?更合理
mMode = Mode.Default if (isList && ruleStr.startsWith(":")) {
ruleStr0.substring(2)
}
ruleStr0.startsWith("@XPath:", true) -> {
mMode = Mode.XPath
ruleStr0.substring(7)
}
ruleStr0.startsWith("/") -> {//XPath特征很明显,无需配置单独的识别标头
mMode = Mode.XPath
ruleStr0
}
ruleStr0.startsWith("@Json:", true) -> {
mMode = Mode.Json
ruleStr0.substring(6)
}
( ruleStr0[1] == '.' || ruleStr0[1] == '[') && ruleStr0[0] == '$' || isJSON -> {
mMode = Mode.Json
ruleStr0
}
else -> {
mMode = Mode.Default
ruleStr0
}
}
//拆分为规则列表
var start = if(isList && ruleStr.startsWith(":")){ //仅首字符为:时为AllInOne,其实:与伪类选择器冲突,建议改成?更合理
mMode = Mode.Regex mMode = Mode.Regex
isRegex = true isRegex = true
1 start = 1
}else 0 }
var tmp: String var tmp: String
val jsMatcher = JS_PATTERN.matcher(ruleStr) val jsMatcher = JS_PATTERN.matcher(ruleStr)
while (jsMatcher.find()) { while (jsMatcher.find()) {
if (jsMatcher.start() > start) { if (jsMatcher.start() > start) {
tmp = ruleStr.substring(start, jsMatcher.start()).trim { it <= ' ' } tmp = ruleStr.substring(start, jsMatcher.start()).trim { it <= ' ' }
if (tmp.isNotEmpty()) { if (tmp.isNotEmpty()) {
ruleList.add(SourceRule(mode(tmp), mMode)) ruleList.add(SourceRule(tmp, mMode))
} }
} }
ruleList.add(SourceRule(jsMatcher.group(2) ?: jsMatcher.group(1), Mode.Js)) ruleList.add(SourceRule(jsMatcher.group(2) ?: jsMatcher.group(1), Mode.Js))
@ -410,7 +383,7 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
if (ruleStr.length > start) { if (ruleStr.length > start) {
tmp = ruleStr.substring(start).trim { it <= ' ' } tmp = ruleStr.substring(start).trim { it <= ' ' }
if (tmp.isNotEmpty()) { if (tmp.isNotEmpty()) {
ruleList.add(SourceRule(mode(tmp), mMode)) ruleList.add(SourceRule(tmp, mMode))
} }
} }
@ -436,8 +409,37 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
init { init {
this.mode = mainMode this.mode = mainMode
rule = when {
ruleStr.startsWith("@CSS:", true) -> {
mode = Mode.Default
ruleStr
}
ruleStr.startsWith("@@") -> {
mode = Mode.Default
ruleStr.substring(2)
}
ruleStr.startsWith("@XPath:", true) -> {
mode = Mode.XPath
ruleStr.substring(7)
}
ruleStr.startsWith("/") -> {//XPath特征很明显,无需配置单独的识别标头
mode = Mode.XPath
ruleStr
}
ruleStr.startsWith("@Json:", true) -> {
mode = Mode.Json
ruleStr.substring(6)
}
(ruleStr[1] == '.' || ruleStr[1] == '[') && ruleStr.startsWith("$.") || isJSON -> {
mode = Mode.Json
ruleStr
}
else -> {
ruleStr
}
}
//分离put //分离put
rule = splitPutRule(ruleStr, putMap) rule = splitPutRule(rule, putMap)
//@get,{{ }}, 拆分 //@get,{{ }}, 拆分
var start = 0 var start = 0
var tmp: String var tmp: String

@ -149,7 +149,8 @@ class AnalyzeUrl(
} }
if (urlHasQuery.length != ruleUrl.length) { if (urlHasQuery.length != ruleUrl.length) {
GSON.fromJsonObject<UrlOption>(ruleUrl.substring(urlHasQuery.length + 1).trim{ it < '!'})?.let { option -> GSON.fromJsonObject<UrlOption>(
ruleUrl.substring(urlHasQuery.length + 1).trim { it < '!' })?.let { option ->
option.method?.let { option.method?.let {
if (it.equals("POST", true)) method = RequestMethod.POST if (it.equals("POST", true)) method = RequestMethod.POST

@ -1,8 +1,9 @@
package io.legado.app.model.analyzeRule package io.legado.app.model.analyzeRule
import io.legado.app.utils.isJson import io.legado.app.utils.isJson
import java.util.ArrayList import java.util.*
import java.util.regex.Pattern import java.util.regex.Pattern
import kotlin.collections.HashMap
//通用的规则切分处理 //通用的规则切分处理
@ -70,6 +71,7 @@ class RuleAnalyzer(data: String, code: Boolean = false) {
} }
return false return false
} }
/** /**
* 从剩余字串中拉出一个字符串直到但不包括匹配序列匹配参数列表中一项即为匹配或剩余字串用完 * 从剩余字串中拉出一个字符串直到但不包括匹配序列匹配参数列表中一项即为匹配或剩余字串用完
* @param seq 匹配字符串序列 * @param seq 匹配字符串序列
@ -380,7 +382,12 @@ class RuleAnalyzer(data: String, code: Boolean = false) {
val posPre = pos //记录consumeTo匹配位置 val posPre = pos //记录consumeTo匹配位置
if (consumeTo(endStr)) { if (consumeTo(endStr)) {
val frv = fr(queue.substring(posPre, pos)) val frv = fr(queue.substring(posPre, pos))
st.append(queue.substring(startX, posPre - startStr.length) + frv) //压入内嵌规则前的内容,及内嵌规则解析得到的字符串 st.append(
queue.substring(
startX,
posPre - startStr.length
) + frv
) //压入内嵌规则前的内容,及内嵌规则解析得到的字符串
pos += endStr.length //跳过结束字符串 pos += endStr.length //跳过结束字符串
startX = pos //记录下次规则起点 startX = pos //记录下次规则起点
} }
@ -394,8 +401,10 @@ class RuleAnalyzer(data: String, code: Boolean = false) {
//-----------此处向下的函数和变量都未被使用,但以后要用-------- //-----------此处向下的函数和变量都未被使用,但以后要用--------
val ruleTypeList = ArrayList<String>() val ruleTypeList = ArrayList<String>()
//设置平衡组函数,json或JavaScript时设置成chompCodeBalanced,否则为chompRuleBalanced //设置平衡组函数,json或JavaScript时设置成chompCodeBalanced,否则为chompRuleBalanced
val chompBalanced = if (code) ::chompCodeBalanced else ::chompRuleBalanced val chompBalanced = if (code) ::chompCodeBalanced else ::chompRuleBalanced
enum class Mode { enum class Mode {
XPath, Json, Default, Js, Regex XPath, Json, Default, Js, Regex
} }
@ -538,12 +547,13 @@ class RuleAnalyzer(data: String, code: Boolean = false) {
/** /**
* 参数字符串 * 参数字符串
*/ */
private val STARTSTRURL = arrayOf(",{",) private val STARTSTRURL = arrayOf(",{")
private val regexPattern = Pattern.compile("\\$\\d{1,2}") private val regexPattern = Pattern.compile("\\$\\d{1,2}")
private val putPattern = Pattern.compile("@put:(\\{[^}]+?\\})", Pattern.CASE_INSENSITIVE) private val putPattern = Pattern.compile("@put:(\\{[^}]+?\\})", Pattern.CASE_INSENSITIVE)
private val getPattern = Pattern.compile("@get:\\{([^}]+?)\\}", Pattern.CASE_INSENSITIVE) private val getPattern = Pattern.compile("@get:\\{([^}]+?)\\}", Pattern.CASE_INSENSITIVE)
private val evalPattern = Pattern.compile("\\{\\{[\\w\\W]*?\\}\\}", Pattern.CASE_INSENSITIVE) private val evalPattern =
Pattern.compile("\\{\\{[\\w\\W]*?\\}\\}", Pattern.CASE_INSENSITIVE)
val ENDSTR = mapOf( val ENDSTR = mapOf(
"<js>" to "</js>", "<js>" to "</js>",
@ -553,18 +563,35 @@ class RuleAnalyzer(data: String, code: Boolean = false) {
/** /**
* 规则起始字符串 * 规则起始字符串
*/ */
private val STARTSTR = arrayOf("@js:","<js>","</js>","##","@@","@" private val STARTSTR = arrayOf(
,"{{@", "{{","}}" "@js:",
,"}" "<js>",
, "{@", "{/", "{$" "</js>",
, "{class" "##",
, "{id" "@@",
, "{tag" "@",
, "{text" "{{@",
, "{children" "{{",
,"/","$","@xpath:","@json:","@css:" "}}",
,"||", "&&", "%%" "}",
,"@get:{","@put:{" "{@",
"{/",
"{$",
"{class",
"{id",
"{tag",
"{text",
"{children",
"/",
"$",
"@xpath:",
"@json:",
"@css:",
"||",
"&&",
"%%",
"@get:{",
"@put:{"
) )
/** /**

@ -415,7 +415,8 @@ object ReadBook {
else -> chapter.title else -> chapter.title
} }
val contents = contentProcessor!!.getContent(book, chapter.title, content) val contents = contentProcessor!!.getContent(book, chapter.title, content)
val textChapter = ChapterProvider.getTextChapter(book, chapter,contents,chapterSize) val textChapter =
ChapterProvider.getTextChapter(book, chapter, contents, chapterSize)
val offset = chapter.index - durChapterIndex val offset = chapter.index - durChapterIndex
if (upContent) callBack?.upContent(offset, resetPageOffset) if (upContent) callBack?.upContent(offset, resetPageOffset)

@ -28,7 +28,10 @@ object HtmlFormatter {
val sb = StringBuffer() val sb = StringBuffer()
var endPos = 0 var endPos = 0
for(pattern in listOf("<img[^>]*data-[^=]*= *\"([^\"])\"[^>]*>","<img[^>]*src *= *\"([^\"{]+(?:\\{(?:[^{}]|\\{[^{}]*\\})*\\})?)\"[^>]*>")){ for (pattern in listOf(
"<img[^>]*data-[^=]*= *\"([^\"])\"[^>]*>",
"<img[^>]*src *= *\"([^\"{]+(?:\\{(?:[^{}]|\\{[^{}]*\\})*\\})?)\"[^>]*>"
)) {
var appendPos = 0 var appendPos = 0
val matcher = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE).matcher(keepImgHtml) val matcher = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE).matcher(keepImgHtml)
while (matcher.find()) { while (matcher.find()) {
@ -36,7 +39,10 @@ object HtmlFormatter {
val urlBefore = url.substringBefore(',') val urlBefore = url.substringBefore(',')
val strBefore = keepImgHtml.substring(appendPos, matcher.start()) val strBefore = keepImgHtml.substring(appendPos, matcher.start())
sb.append( sb.append(
if(strBefore.isBlank()) strBefore else strBefore.replace("\n", "\n  ") //缩进图片之间的非空白段落 if (strBefore.isBlank()) strBefore else strBefore.replace(
"\n",
"\n  "
) //缩进图片之间的非空白段落
) )
sb.append( sb.append(
"<img src=\"${ "<img src=\"${
@ -52,7 +58,9 @@ object HtmlFormatter {
} }
if (endPos < keepImgHtml.length) { if (endPos < keepImgHtml.length) {
sb.append( keepImgHtml.substring( endPos, keepImgHtml.length ).replace("\n","\n  ") ) //缩进图片之后的非空白段落 sb.append(
keepImgHtml.substring(endPos, keepImgHtml.length).replace("\n", "\n  ")
) //缩进图片之后的非空白段落
} }
return sb.toString() return sb.toString()
} }

Loading…
Cancel
Save