forked from LiveCarta/BookConverter
epub converter: add internal links processing
- fix cleaning headings - fix when chapter mark is not on the 1 level
This commit is contained in:
@@ -115,8 +115,12 @@ def _process_lists(body_tag):
|
||||
|
||||
def clean_headings_content(content: Tag, title: str):
|
||||
for child in content.contents:
|
||||
if child.text and re.sub(r'([\n\t\xa0])', '', child.text):
|
||||
text = re.sub(r'([\n\t\xa0])', ' ', child.text)
|
||||
if isinstance(child, NavigableString):
|
||||
text = child
|
||||
else:
|
||||
text = child.text
|
||||
if text and re.sub(r'([\n\t\xa0])', '', text):
|
||||
text = re.sub(r'([\n\t\xa0])', ' ', text)
|
||||
text = re.sub(r' +', ' ', text).strip()
|
||||
if title == text:
|
||||
child.extract()
|
||||
@@ -196,10 +200,6 @@ def preprocess_footnotes(source_html_tag: Tag, href2soup_html: dict = None, note
|
||||
|
||||
return unicode_string.strip()
|
||||
|
||||
def remove_internal_links_with_text(t):
|
||||
for tag_a in t.find_all('a', {'href': re.compile('(^.+\.(html|xhtml)#.+)|(^#.+)')}):
|
||||
tag_a.decompose()
|
||||
|
||||
for i, noteref_tag in enumerate(noterefs_tags):
|
||||
href = noteref_tag.attrs['href']
|
||||
file, element_id = parse_a_tag_href(href)
|
||||
@@ -208,7 +208,7 @@ def preprocess_footnotes(source_html_tag: Tag, href2soup_html: dict = None, note
|
||||
else:
|
||||
target_html_tag = href2soup_html.get(file)
|
||||
if not target_html_tag:
|
||||
print(f'Error. for\n{noteref_tag}\ninvalid path: {file} found.')
|
||||
print(f'Error while footnotes processing. For {noteref_tag} invalid path: {file}.')
|
||||
continue
|
||||
|
||||
possible_footnote = 'note|footnote|endnote|rearenote'
|
||||
@@ -218,7 +218,6 @@ def preprocess_footnotes(source_html_tag: Tag, href2soup_html: dict = None, note
|
||||
expected_footnote_tags = verify_footnote_tag(expected_footnote_tags)
|
||||
footnote_tag = expected_footnote_tags[0]
|
||||
replace_with_livecarta_anchor_tag(noteref_tag, i)
|
||||
remove_internal_links_with_text(footnote_tag)
|
||||
content = get_footnote_tags2str(footnote_tag)
|
||||
|
||||
footnote_tag.decompose()
|
||||
@@ -227,45 +226,19 @@ def preprocess_footnotes(source_html_tag: Tag, href2soup_html: dict = None, note
|
||||
return footnotes
|
||||
|
||||
|
||||
def add_fonts():
|
||||
pass
|
||||
|
||||
|
||||
def unwrap_structural_tags(body_tag):
|
||||
|
||||
def _add_span_to_save_ids_for_links(tag_to_be_removed):
|
||||
if tag_to_be_removed.attrs.get('id'):
|
||||
new_tag = body_tag.new_tag("span")
|
||||
new_tag.attrs['id'] = tag_to_be_removed.attrs['id']
|
||||
tag_to_be_removed.insert_before(new_tag)
|
||||
|
||||
structural_tags_names = [
|
||||
'div', 'section', 'article', 'main', 'body', 'html', 'aside', 'canvas', 'data',
|
||||
'figure', 'footer', 'iframe', 'span', 'p'
|
||||
]
|
||||
|
||||
for div in body_tag.find_all("div"):
|
||||
if div.contents:
|
||||
is_not_struct_tag = [child.name not in structural_tags_names for child in div.contents]
|
||||
if all(is_not_struct_tag):
|
||||
div.name = 'p'
|
||||
continue
|
||||
div.unwrap()
|
||||
|
||||
for s in body_tag.find_all("section"):
|
||||
s.unwrap()
|
||||
|
||||
for s in body_tag.find_all("article"):
|
||||
s.unwrap()
|
||||
|
||||
for s in body_tag.find_all("aside"):
|
||||
s.name = 'blockquote'
|
||||
|
||||
for s in body_tag.find_all("main"):
|
||||
s.unwrap()
|
||||
|
||||
for s in body_tag.find_all("body"):
|
||||
s.unwrap()
|
||||
|
||||
for s in body_tag.find_all("html"):
|
||||
s.unwrap()
|
||||
|
||||
for s in body_tag.find_all("header"):
|
||||
s.name = 'span'
|
||||
|
||||
# should be before other tags processing, not to remove converter empty tags with id
|
||||
# not all cases, if span has <p>s and NavigableString, it won't unwrap
|
||||
for s in body_tag.find_all("span"):
|
||||
if s.contents:
|
||||
@@ -274,6 +247,55 @@ def unwrap_structural_tags(body_tag):
|
||||
continue
|
||||
s.unwrap()
|
||||
|
||||
for div in body_tag.find_all("div"):
|
||||
if div.contents:
|
||||
is_not_struct_tag = [child.name not in structural_tags_names for child in div.contents]
|
||||
if all(is_not_struct_tag):
|
||||
div.name = 'p'
|
||||
continue
|
||||
|
||||
_add_span_to_save_ids_for_links(div)
|
||||
div.unwrap()
|
||||
|
||||
for s in body_tag.find_all("section"):
|
||||
_add_span_to_save_ids_for_links(s)
|
||||
s.unwrap()
|
||||
|
||||
for s in body_tag.find_all("article"):
|
||||
_add_span_to_save_ids_for_links(s)
|
||||
s.unwrap()
|
||||
|
||||
for s in body_tag.find_all("aside"):
|
||||
s.name = 'blockquote'
|
||||
|
||||
for s in body_tag.find_all("main"):
|
||||
_add_span_to_save_ids_for_links(s)
|
||||
s.unwrap()
|
||||
|
||||
for s in body_tag.find_all("body"):
|
||||
_add_span_to_save_ids_for_links(s)
|
||||
s.unwrap()
|
||||
|
||||
for s in body_tag.find_all("html"):
|
||||
_add_span_to_save_ids_for_links(s)
|
||||
s.unwrap()
|
||||
|
||||
for s in body_tag.find_all("header"):
|
||||
s.name = 'span'
|
||||
|
||||
# check marks for chapter starting are on the same 1 level
|
||||
marks = body_tag.find_all(attrs={'class': 'converter-chapter-mark'})
|
||||
parents_marks_are_body = [x.parent == body_tag for x in marks]
|
||||
|
||||
# fix marks to be on 1 level
|
||||
if not all(parents_marks_are_body):
|
||||
for x in marks:
|
||||
while x.parent != body_tag:
|
||||
x.parent.unwrap() # warning! could reflect on formatting/internal links in some cases
|
||||
|
||||
parents_marks_are_body = [x.parent == body_tag for x in marks]
|
||||
assert all(parents_marks_are_body), 'Anchor for chapter is deeper than 2 level.'
|
||||
|
||||
_preprocessing_headings(body_tag)
|
||||
|
||||
for node in body_tag:
|
||||
@@ -290,12 +312,12 @@ def unwrap_structural_tags(body_tag):
|
||||
|
||||
|
||||
def get_tags_between_ids(first_id, href, html_soup):
|
||||
h_marked = html_soup.find(attrs={'id': first_id, 'class': 'internal-mark'})
|
||||
h_marked = html_soup.find(attrs={'id': first_id, 'class': 'converter-chapter-mark'})
|
||||
if h_marked:
|
||||
p = h_marked.next_sibling
|
||||
tags = []
|
||||
while p:
|
||||
if p.name == 'h1' and p.attrs.get('class') == 'internal-mark':
|
||||
if p.name == 'tmp' and p.attrs.get('class') == 'converter-chapter-mark':
|
||||
break
|
||||
tags.append(p)
|
||||
p = p.next_sibling
|
||||
@@ -330,7 +352,7 @@ def prepare_title_and_content(title, chapter_tag: BeautifulSoup, remove_title_fr
|
||||
preprocess_table(chapter_tag)
|
||||
# 2. class removal
|
||||
for tag in chapter_tag.find_all(recursive=True):
|
||||
if hasattr(tag, 'attrs') and tag.attrs.get('class'):
|
||||
if hasattr(tag, 'attrs') and tag.attrs.get('class') and (tag.attrs.get('class') not in ['link-anchor']):
|
||||
del tag.attrs['class']
|
||||
|
||||
# content_str = re.sub(r'([\n\t\xa0])', ' ', str(content_tag))
|
||||
|
||||
Reference in New Issue
Block a user