mirror of
https://github.com/gedoor/legado.git
synced 2024-09-01 09:34:25 +08:00
优化
This commit is contained in:
parent
e2d187f38a
commit
493524b402
@ -119,23 +119,18 @@ class EpubFile(var book: Book) {
|
||||
|
||||
private fun getContent(chapter: BookChapter): String? {
|
||||
/*获取当前章节文本*/
|
||||
return getChildChapter(chapter, chapter.url)
|
||||
}
|
||||
|
||||
private fun getChildChapter(chapter: BookChapter, href: String): String? {
|
||||
epubBook?.let {
|
||||
val body = Jsoup.parse(String(it.resources.getByHref(href).data, mCharset)).body()
|
||||
val body =
|
||||
Jsoup.parse(String(it.resources.getByHref(chapter.url).data, mCharset)).body()
|
||||
|
||||
if (chapter.url == href) {
|
||||
val startFragmentId = chapter.startFragmentId
|
||||
val endFragmentId = chapter.endFragmentId
|
||||
/*一些书籍依靠href索引的resource会包含多个章节,需要依靠fragmentId来截取到当前章节的内容*/
|
||||
/*注:这里较大增加了内容加载的时间,所以首次获取内容后可存储到本地cache,减少重复加载*/
|
||||
if (!startFragmentId.isNullOrBlank())
|
||||
body.getElementById(startFragmentId)?.previousElementSiblings()?.remove()
|
||||
if (!endFragmentId.isNullOrBlank() && endFragmentId != startFragmentId)
|
||||
body.getElementById(endFragmentId)?.nextElementSiblings()?.remove()
|
||||
}
|
||||
val startFragmentId = chapter.startFragmentId
|
||||
val endFragmentId = chapter.endFragmentId
|
||||
/*一些书籍依靠href索引的resource会包含多个章节,需要依靠fragmentId来截取到当前章节的内容*/
|
||||
/*注:这里较大增加了内容加载的时间,所以首次获取内容后可存储到本地cache,减少重复加载*/
|
||||
if (!startFragmentId.isNullOrBlank())
|
||||
body.getElementById(startFragmentId)?.previousElementSiblings()?.remove()
|
||||
if (!endFragmentId.isNullOrBlank() && endFragmentId != startFragmentId)
|
||||
body.getElementById(endFragmentId)?.nextElementSiblings()?.remove()
|
||||
|
||||
/*选择去除正文中的H标签,部分书籍标题与阅读标题重复待优化*/
|
||||
var tag = Book.hTag
|
||||
|
@ -10,251 +10,255 @@ import java.util.Set;
|
||||
/**
|
||||
* The table of contents of the book.
|
||||
* The TableOfContents is a tree structure at the root it is a list of TOCReferences, each if which may have as children another list of TOCReferences.
|
||||
*
|
||||
* <p>
|
||||
* The table of contents is used by epub as a quick index to chapters and sections within chapters.
|
||||
* It may contain duplicate entries, may decide to point not to certain chapters, etc.
|
||||
*
|
||||
* <p>
|
||||
* See the spine for the complete list of sections in the order in which they should be read.
|
||||
*
|
||||
* @see Spine
|
||||
*
|
||||
* @author paul
|
||||
* @see Spine
|
||||
*/
|
||||
public class TableOfContents implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -3147391239966275152L;
|
||||
private static final long serialVersionUID = -3147391239966275152L;
|
||||
|
||||
public static final String DEFAULT_PATH_SEPARATOR = "/";
|
||||
public static final String DEFAULT_PATH_SEPARATOR = "/";
|
||||
|
||||
private List<TOCReference> tocReferences;
|
||||
private List<TOCReference> tocReferences;
|
||||
|
||||
public TableOfContents() {
|
||||
this(new ArrayList<>());
|
||||
}
|
||||
public TableOfContents() {
|
||||
this(new ArrayList<>());
|
||||
}
|
||||
|
||||
public TableOfContents(List<TOCReference> tocReferences) {
|
||||
this.tocReferences = tocReferences;
|
||||
}
|
||||
public TableOfContents(List<TOCReference> tocReferences) {
|
||||
this.tocReferences = tocReferences;
|
||||
}
|
||||
|
||||
public List<TOCReference> getTocReferences() {
|
||||
return tocReferences;
|
||||
}
|
||||
public List<TOCReference> getTocReferences() {
|
||||
return tocReferences;
|
||||
}
|
||||
|
||||
public void setTocReferences(List<TOCReference> tocReferences) {
|
||||
this.tocReferences = tocReferences;
|
||||
}
|
||||
public void setTocReferences(List<TOCReference> tocReferences) {
|
||||
this.tocReferences = tocReferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls addTOCReferenceAtLocation after splitting the path using the DEFAULT_PATH_SEPARATOR.
|
||||
* @return the new TOCReference
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public TOCReference addSection(Resource resource, String path) {
|
||||
return addSection(resource, path, DEFAULT_PATH_SEPARATOR);
|
||||
}
|
||||
/**
|
||||
* Calls addTOCReferenceAtLocation after splitting the path using the DEFAULT_PATH_SEPARATOR.
|
||||
*
|
||||
* @return the new TOCReference
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public TOCReference addSection(Resource resource, String path) {
|
||||
return addSection(resource, path, DEFAULT_PATH_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls addTOCReferenceAtLocation after splitting the path using the given pathSeparator.
|
||||
*
|
||||
* @param resource resource
|
||||
* @param path path
|
||||
* @param pathSeparator pathSeparator
|
||||
* @return the new TOCReference
|
||||
*/
|
||||
public TOCReference addSection(Resource resource, String path,
|
||||
String pathSeparator) {
|
||||
String[] pathElements = path.split(pathSeparator);
|
||||
return addSection(resource, pathElements);
|
||||
}
|
||||
/**
|
||||
* Calls addTOCReferenceAtLocation after splitting the path using the given pathSeparator.
|
||||
*
|
||||
* @param resource resource
|
||||
* @param path path
|
||||
* @param pathSeparator pathSeparator
|
||||
* @return the new TOCReference
|
||||
*/
|
||||
public TOCReference addSection(Resource resource, String path,
|
||||
String pathSeparator) {
|
||||
String[] pathElements = path.split(pathSeparator);
|
||||
return addSection(resource, pathElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the first TOCReference in the given list that has the same title as the given Title.
|
||||
*
|
||||
* @param title title
|
||||
* @param tocReferences tocReferences
|
||||
* @return null if not found.
|
||||
*/
|
||||
private static TOCReference findTocReferenceByTitle(String title,
|
||||
List<TOCReference> tocReferences) {
|
||||
for (TOCReference tocReference : tocReferences) {
|
||||
if (title.equals(tocReference.getTitle())) {
|
||||
/**
|
||||
* Finds the first TOCReference in the given list that has the same title as the given Title.
|
||||
*
|
||||
* @param title title
|
||||
* @param tocReferences tocReferences
|
||||
* @return null if not found.
|
||||
*/
|
||||
private static TOCReference findTocReferenceByTitle(String title,
|
||||
List<TOCReference> tocReferences) {
|
||||
for (TOCReference tocReference : tocReferences) {
|
||||
if (title.equals(tocReference.getTitle())) {
|
||||
return tocReference;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given Resources to the TableOfContents at the location specified by the pathElements.
|
||||
* <p>
|
||||
* Example:
|
||||
* Calling this method with a Resource and new String[] {"chapter1", "paragraph1"} will result in the following:
|
||||
* <ul>
|
||||
* <li>a TOCReference with the title "chapter1" at the root level.<br/>
|
||||
* If this TOCReference did not yet exist it will have been created and does not point to any resource</li>
|
||||
* <li>A TOCReference that has the title "paragraph1". This TOCReference will be the child of TOCReference "chapter1" and
|
||||
* will point to the given Resource</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param resource resource
|
||||
* @param pathElements pathElements
|
||||
* @return the new TOCReference
|
||||
*/
|
||||
public TOCReference addSection(Resource resource, String[] pathElements) {
|
||||
if (pathElements == null || pathElements.length == 0) {
|
||||
return null;
|
||||
}
|
||||
TOCReference result = null;
|
||||
List<TOCReference> currentTocReferences = this.tocReferences;
|
||||
for (String currentTitle : pathElements) {
|
||||
result = findTocReferenceByTitle(currentTitle, currentTocReferences);
|
||||
if (result == null) {
|
||||
result = new TOCReference(currentTitle, null);
|
||||
currentTocReferences.add(result);
|
||||
}
|
||||
currentTocReferences = result.getChildren();
|
||||
}
|
||||
result.setResource(resource);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given Resources to the TableOfContents at the location specified by the pathElements.
|
||||
* <p>
|
||||
* Example:
|
||||
* Calling this method with a Resource and new int[] {0, 0} will result in the following:
|
||||
* <ul>
|
||||
* <li>a TOCReference at the root level.<br/>
|
||||
* If this TOCReference did not yet exist it will have been created with a title of "" and does not point to any resource</li>
|
||||
* <li>A TOCReference that points to the given resource and is a child of the previously created TOCReference.<br/>
|
||||
* If this TOCReference didn't exist yet it will be created and have a title of ""</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param resource resource
|
||||
* @param pathElements pathElements
|
||||
* @return the new TOCReference
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public TOCReference addSection(Resource resource, int[] pathElements,
|
||||
String sectionTitlePrefix, String sectionNumberSeparator) {
|
||||
if (pathElements == null || pathElements.length == 0) {
|
||||
return null;
|
||||
}
|
||||
TOCReference result = null;
|
||||
List<TOCReference> currentTocReferences = this.tocReferences;
|
||||
for (int i = 0; i < pathElements.length; i++) {
|
||||
int currentIndex = pathElements[i];
|
||||
if (currentIndex > 0 && currentIndex < (currentTocReferences.size()
|
||||
- 1)) {
|
||||
result = currentTocReferences.get(currentIndex);
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
if (result == null) {
|
||||
paddTOCReferences(currentTocReferences, pathElements, i,
|
||||
sectionTitlePrefix, sectionNumberSeparator);
|
||||
result = currentTocReferences.get(currentIndex);
|
||||
}
|
||||
currentTocReferences = result.getChildren();
|
||||
}
|
||||
result.setResource(resource);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void paddTOCReferences(List<TOCReference> currentTocReferences,
|
||||
int[] pathElements, int pathPos, String sectionPrefix,
|
||||
String sectionNumberSeparator) {
|
||||
for (int i = currentTocReferences.size(); i <= pathElements[pathPos]; i++) {
|
||||
String sectionTitle = createSectionTitle(pathElements, pathPos, i,
|
||||
sectionPrefix,
|
||||
sectionNumberSeparator);
|
||||
currentTocReferences.add(new TOCReference(sectionTitle, null));
|
||||
}
|
||||
}
|
||||
|
||||
private String createSectionTitle(int[] pathElements, int pathPos,
|
||||
int lastPos,
|
||||
String sectionPrefix, String sectionNumberSeparator) {
|
||||
StringBuilder title = new StringBuilder(sectionPrefix);
|
||||
for (int i = 0; i < pathPos; i++) {
|
||||
if (i > 0) {
|
||||
title.append(sectionNumberSeparator);
|
||||
}
|
||||
title.append(pathElements[i] + 1);
|
||||
}
|
||||
if (pathPos > 0) {
|
||||
title.append(sectionNumberSeparator);
|
||||
}
|
||||
title.append(lastPos + 1);
|
||||
return title.toString();
|
||||
}
|
||||
|
||||
public TOCReference addTOCReference(TOCReference tocReference) {
|
||||
if (tocReferences == null) {
|
||||
tocReferences = new ArrayList<>();
|
||||
}
|
||||
tocReferences.add(tocReference);
|
||||
return tocReference;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given Resources to the TableOfContents at the location specified by the pathElements.
|
||||
*
|
||||
* Example:
|
||||
* Calling this method with a Resource and new String[] {"chapter1", "paragraph1"} will result in the following:
|
||||
* <ul>
|
||||
* <li>a TOCReference with the title "chapter1" at the root level.<br/>
|
||||
* If this TOCReference did not yet exist it will have been created and does not point to any resource</li>
|
||||
* <li>A TOCReference that has the title "paragraph1". This TOCReference will be the child of TOCReference "chapter1" and
|
||||
* will point to the given Resource</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param resource resource
|
||||
* @param pathElements pathElements
|
||||
* @return the new TOCReference
|
||||
*/
|
||||
public TOCReference addSection(Resource resource, String[] pathElements) {
|
||||
if (pathElements == null || pathElements.length == 0) {
|
||||
return null;
|
||||
/**
|
||||
* All unique references (unique by href) in the order in which they are referenced to in the table of contents.
|
||||
*
|
||||
* @return All unique references (unique by href) in the order in which they are referenced to in the table of contents.
|
||||
*/
|
||||
public List<Resource> getAllUniqueResources() {
|
||||
Set<String> uniqueHrefs = new HashSet<>();
|
||||
List<Resource> result = new ArrayList<>();
|
||||
getAllUniqueResources(uniqueHrefs, result, tocReferences);
|
||||
return result;
|
||||
}
|
||||
TOCReference result = null;
|
||||
List<TOCReference> currentTocReferences = this.tocReferences;
|
||||
for (String currentTitle : pathElements) {
|
||||
result = findTocReferenceByTitle(currentTitle, currentTocReferences);
|
||||
if (result == null) {
|
||||
result = new TOCReference(currentTitle, null);
|
||||
currentTocReferences.add(result);
|
||||
}
|
||||
currentTocReferences = result.getChildren();
|
||||
}
|
||||
result.setResource(resource);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given Resources to the TableOfContents at the location specified by the pathElements.
|
||||
*
|
||||
* Example:
|
||||
* Calling this method with a Resource and new int[] {0, 0} will result in the following:
|
||||
* <ul>
|
||||
* <li>a TOCReference at the root level.<br/>
|
||||
* If this TOCReference did not yet exist it will have been created with a title of "" and does not point to any resource</li>
|
||||
* <li>A TOCReference that points to the given resource and is a child of the previously created TOCReference.<br/>
|
||||
* If this TOCReference didn't exist yet it will be created and have a title of ""</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param resource resource
|
||||
* @param pathElements pathElements
|
||||
* @return the new TOCReference
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public TOCReference addSection(Resource resource, int[] pathElements,
|
||||
String sectionTitlePrefix, String sectionNumberSeparator) {
|
||||
if (pathElements == null || pathElements.length == 0) {
|
||||
return null;
|
||||
private static void getAllUniqueResources(
|
||||
Set<String> uniqueHrefs,
|
||||
List<Resource> result,
|
||||
List<TOCReference> tocReferences
|
||||
) {
|
||||
for (TOCReference tocReference : tocReferences) {
|
||||
Resource resource = tocReference.getResource();
|
||||
if (resource != null && !uniqueHrefs.contains(resource.getHref())) {
|
||||
uniqueHrefs.add(resource.getHref());
|
||||
result.add(resource);
|
||||
}
|
||||
getAllUniqueResources(uniqueHrefs, result, tocReference.getChildren());
|
||||
}
|
||||
}
|
||||
TOCReference result = null;
|
||||
List<TOCReference> currentTocReferences = this.tocReferences;
|
||||
for (int i = 0; i < pathElements.length; i++) {
|
||||
int currentIndex = pathElements[i];
|
||||
if (currentIndex > 0 && currentIndex < (currentTocReferences.size()
|
||||
- 1)) {
|
||||
result = currentTocReferences.get(currentIndex);
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
if (result == null) {
|
||||
paddTOCReferences(currentTocReferences, pathElements, i,
|
||||
sectionTitlePrefix, sectionNumberSeparator);
|
||||
result = currentTocReferences.get(currentIndex);
|
||||
}
|
||||
currentTocReferences = result.getChildren();
|
||||
|
||||
/**
|
||||
* The total number of references in this table of contents.
|
||||
*
|
||||
* @return The total number of references in this table of contents.
|
||||
*/
|
||||
public int size() {
|
||||
return getTotalSize(tocReferences);
|
||||
}
|
||||
result.setResource(resource);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void paddTOCReferences(List<TOCReference> currentTocReferences,
|
||||
int[] pathElements, int pathPos, String sectionPrefix,
|
||||
String sectionNumberSeparator) {
|
||||
for (int i = currentTocReferences.size(); i <= pathElements[pathPos]; i++) {
|
||||
String sectionTitle = createSectionTitle(pathElements, pathPos, i,
|
||||
sectionPrefix,
|
||||
sectionNumberSeparator);
|
||||
currentTocReferences.add(new TOCReference(sectionTitle, null));
|
||||
private static int getTotalSize(Collection<TOCReference> tocReferences) {
|
||||
int result = tocReferences.size();
|
||||
for (TOCReference tocReference : tocReferences) {
|
||||
result += getTotalSize(tocReference.getChildren());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private String createSectionTitle(int[] pathElements, int pathPos,
|
||||
int lastPos,
|
||||
String sectionPrefix, String sectionNumberSeparator) {
|
||||
StringBuilder title = new StringBuilder(sectionPrefix);
|
||||
for (int i = 0; i < pathPos; i++) {
|
||||
if (i > 0) {
|
||||
title.append(sectionNumberSeparator);
|
||||
}
|
||||
title.append(pathElements[i] + 1);
|
||||
/**
|
||||
* The maximum depth of the reference tree
|
||||
*
|
||||
* @return The maximum depth of the reference tree
|
||||
*/
|
||||
public int calculateDepth() {
|
||||
return calculateDepth(tocReferences, 0);
|
||||
}
|
||||
if (pathPos > 0) {
|
||||
title.append(sectionNumberSeparator);
|
||||
|
||||
private int calculateDepth(List<TOCReference> tocReferences,
|
||||
int currentDepth) {
|
||||
int maxChildDepth = 0;
|
||||
for (TOCReference tocReference : tocReferences) {
|
||||
int childDepth = calculateDepth(tocReference.getChildren(), 1);
|
||||
if (childDepth > maxChildDepth) {
|
||||
maxChildDepth = childDepth;
|
||||
}
|
||||
}
|
||||
return currentDepth + maxChildDepth;
|
||||
}
|
||||
title.append(lastPos + 1);
|
||||
return title.toString();
|
||||
}
|
||||
|
||||
public TOCReference addTOCReference(TOCReference tocReference) {
|
||||
if (tocReferences == null) {
|
||||
tocReferences = new ArrayList<>();
|
||||
}
|
||||
tocReferences.add(tocReference);
|
||||
return tocReference;
|
||||
}
|
||||
|
||||
/**
|
||||
* All unique references (unique by href) in the order in which they are referenced to in the table of contents.
|
||||
*
|
||||
* @return All unique references (unique by href) in the order in which they are referenced to in the table of contents.
|
||||
*/
|
||||
public List<Resource> getAllUniqueResources() {
|
||||
Set<String> uniqueHrefs = new HashSet<>();
|
||||
List<Resource> result = new ArrayList<>();
|
||||
getAllUniqueResources(uniqueHrefs, result, tocReferences);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void getAllUniqueResources(Set<String> uniqueHrefs,
|
||||
List<Resource> result, List<TOCReference> tocReferences) {
|
||||
for (TOCReference tocReference : tocReferences) {
|
||||
Resource resource = tocReference.getResource();
|
||||
if (resource != null && !uniqueHrefs.contains(resource.getHref())) {
|
||||
uniqueHrefs.add(resource.getHref());
|
||||
result.add(resource);
|
||||
}
|
||||
getAllUniqueResources(uniqueHrefs, result, tocReference.getChildren());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of references in this table of contents.
|
||||
*
|
||||
* @return The total number of references in this table of contents.
|
||||
*/
|
||||
public int size() {
|
||||
return getTotalSize(tocReferences);
|
||||
}
|
||||
|
||||
private static int getTotalSize(Collection<TOCReference> tocReferences) {
|
||||
int result = tocReferences.size();
|
||||
for (TOCReference tocReference : tocReferences) {
|
||||
result += getTotalSize(tocReference.getChildren());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum depth of the reference tree
|
||||
* @return The maximum depth of the reference tree
|
||||
*/
|
||||
public int calculateDepth() {
|
||||
return calculateDepth(tocReferences, 0);
|
||||
}
|
||||
|
||||
private int calculateDepth(List<TOCReference> tocReferences,
|
||||
int currentDepth) {
|
||||
int maxChildDepth = 0;
|
||||
for (TOCReference tocReference : tocReferences) {
|
||||
int childDepth = calculateDepth(tocReference.getChildren(), 1);
|
||||
if (childDepth > maxChildDepth) {
|
||||
maxChildDepth = childDepth;
|
||||
}
|
||||
}
|
||||
return currentDepth + maxChildDepth;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user