Implement replacing Pokemon with links
This commit is contained in:
84
src/epub.py
84
src/epub.py
@@ -1,8 +1,11 @@
|
||||
import ebooklib
|
||||
import logging
|
||||
import re
|
||||
from bs4 import BeautifulSoup, Tag
|
||||
from bs4.element import NavigableString
|
||||
from ebooklib import epub
|
||||
from src.pokemon import Pokemon
|
||||
from typing import List
|
||||
from typing import List, Dict
|
||||
|
||||
POKEMON_ID_PREFIX = "pokemon-id-"
|
||||
|
||||
@@ -16,12 +19,76 @@ def create_pokedex_chapter(pokemon: List[Pokemon]) -> epub.EpubHtml:
|
||||
for p in pokemon:
|
||||
content.append(f'<h2 id="{POKEMON_ID_PREFIX}{p.name.lower()}">{p.name}</h2>')
|
||||
content.append(f' <p><img alt="[Pokemon {p.name}]" src="../{p.img_filepath}"/><br/></p>')
|
||||
content.append(f' <p>{p.description}</p>')
|
||||
for paragraph in p.description.split("\n"):
|
||||
content.append(f' <p>{paragraph}</p>')
|
||||
content.append('')
|
||||
|
||||
chapter.content = "\n".join(content)
|
||||
return chapter
|
||||
|
||||
|
||||
|
||||
|
||||
def patch_chapter(chapter: epub.EpubHtml, pokemon_lookup: Dict[str, Pokemon]):
|
||||
r = re.compile("([:,.!?“”‘’…])")
|
||||
soup: BeautifulSoup = BeautifulSoup(chapter.content, "html.parser")
|
||||
|
||||
def pokemon_name_to_link(key: str, word: str) -> Tag:
|
||||
tag = soup.new_tag("a")
|
||||
tag.string = word
|
||||
tag.attrs["href"] = f"np_pokedex.xhtml#{POKEMON_ID_PREFIX}{key}"
|
||||
tag.attrs["style"] = "color:black;text-decoration:none"
|
||||
return tag
|
||||
|
||||
def patch_string(section: NavigableString) -> List:
|
||||
""" Replace Pokemon with link to Pokemon; requires splitting up the
|
||||
NavigableString into a list of NavigableStrings and Tags. """
|
||||
result = [[]]
|
||||
for word in str(section).split(" "):
|
||||
word_stripped = r.sub("", word)
|
||||
if word_stripped.lower() in pokemon_lookup:
|
||||
word_split = r.split(word)
|
||||
i = word_split.index(word_stripped)
|
||||
if i == 0:
|
||||
# add space if there are no other chars before pokemon
|
||||
result[-1].append(" ")
|
||||
else:
|
||||
# add other chars before pokemon if there are any
|
||||
result[-1].append("".join(word_split[:i]))
|
||||
pokemon_link = pokemon_name_to_link(word_stripped.lower(), word_stripped)
|
||||
result.append(pokemon_link)
|
||||
result.append([])
|
||||
if i + 1 == len(word_split):
|
||||
# add space after pokemon if there are no other chars
|
||||
result[-1].append(" ")
|
||||
else:
|
||||
# add other chars after pokemon if there are any
|
||||
result[-1].append("".join(word_split[i + 1:]))
|
||||
else:
|
||||
result[-1].append(word)
|
||||
|
||||
# convert words back into strings.
|
||||
for i in range(len(result)):
|
||||
if isinstance(result[i], list):
|
||||
result[i] = NavigableString(" ".join(result[i]))
|
||||
return result
|
||||
|
||||
def patch_paragraph(paragraph: Tag):
|
||||
contents = []
|
||||
for section in paragraph.contents:
|
||||
if isinstance(section, NavigableString):
|
||||
contents += patch_string(section)
|
||||
else:
|
||||
patch_paragraph(section)
|
||||
contents.append(section)
|
||||
paragraph.contents = contents
|
||||
|
||||
for p_soup in soup.find_all("p"):
|
||||
words_have_changed, words = False, []
|
||||
patch_paragraph(p_soup)
|
||||
chapter.content = str(soup)
|
||||
|
||||
|
||||
def patch(epub_filepath: str, pokemon: List[Pokemon]):
|
||||
book = epub.read_epub(epub_filepath)
|
||||
|
||||
@@ -36,8 +103,13 @@ def patch(epub_filepath: str, pokemon: List[Pokemon]):
|
||||
img = epub.EpubItem(uid=p.name, file_name=p.img_filepath, media_type='image/png', content=image_content)
|
||||
book.add_item(img)
|
||||
|
||||
# Link to Pokemon looks like this:
|
||||
# <a href="np_pokedex.xhtml#pokemon-id-bulbasaur">Bulbasaur!</a>
|
||||
pokemon_lookup = {p.name.lower(): p for p in pokemon}
|
||||
chapters = [b for b in book.get_items()
|
||||
if isinstance(b, epub.EpubHtml)
|
||||
if b.id.startswith("np_")]
|
||||
for c in chapters:
|
||||
patch_chapter(c, pokemon_lookup)
|
||||
|
||||
epub.write_epub('tmp/test.epub', book, {})
|
||||
logging.info("Written")
|
||||
epub_out = epub_filepath.replace(".", "-with-links.")
|
||||
epub.write_epub(epub_out, book, {})
|
||||
logging.info(f"{epub_out} written.")
|
||||
|
||||
@@ -97,7 +97,7 @@ def get_pokemon() -> List[Pokemon]:
|
||||
# Filter out speculative Pokemon
|
||||
pokemon = [p for p in pokemon if not p.description.startswith("This article's contents will change")]
|
||||
|
||||
logging.info("Loaded Pokemon.")
|
||||
logging.info("Pokemon loaded.")
|
||||
return pokemon
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user