Skip to content

Commit

Permalink
Add build-loi command for updating an LoI file from <figure>s
Browse files Browse the repository at this point in the history
Text from the <figcaption>, if any, is preferred over that from the
 <img>'s alt attribute, though this can be controlled on a per-ID basis.
If the resulting text is empty, default_link_text is used.
  • Loading branch information
apasel422 committed Jun 24, 2024
1 parent c9e9908 commit f7ef917
Show file tree
Hide file tree
Showing 20 changed files with 630 additions and 6 deletions.
33 changes: 33 additions & 0 deletions se/commands/build_loi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""
This module implements the `se build-loi` command.
"""

import argparse

import se
from se.se_epub import SeEpub


def build_loi(plain_output: bool) -> int:
"""
Entry point for `se build-loi`
"""

parser = argparse.ArgumentParser(description="Update the LoI file based on all <figure> elements that contain an <img>.")
parser.add_argument("-a", "--prefer-alt-text", dest="prefer_alt_text", nargs="+", help="prefer alt text over <figcaption> for these <figure> IDs")
parser.add_argument("-d", "--default-link-text", dest="default_link_text", metavar="DEFAULT-LINK-TEXT", type=str, default="TODO", help="link text to use if <figcaption> or alt text is absent or empty")
parser.add_argument("directory", metavar="DIRECTORY", help="a Standard Ebooks source directory")
args = parser.parse_args()

return_code = 0

try:
se_epub = SeEpub(args.directory)
prefer_alt_text = set(args.prefer_alt_text or [])
se_epub.generate_loi(prefer_alt_text=prefer_alt_text, default_link_text=args.default_link_text)

except se.SeException as ex:
se.print_error(ex, plain_output=plain_output)
return_code = ex.code

return return_code
6 changes: 5 additions & 1 deletion se/completions/bash/se
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ _se(){
COMPREPLY=()
local cur="${COMP_WORDS[COMP_CWORD]}"
local prev="${COMP_WORDS[COMP_CWORD-1]}"
local commands="--help --plain --version british2american build build-ids build-images build-manifest build-spine build-title build-toc clean compare-versions create-draft css-select dec2roman extract-ebook find-mismatched-dashes find-mismatched-diacritics find-unusual-characters help hyphenate interactive-replace lint make-url-safe modernize-spelling prepare-release recompose-epub renumber-endnotes roman2dec semanticate shift-endnotes shift-illustrations split-file titlecase typogrify unicode-names version word-count xpath"
local commands="--help --plain --version british2american build build-ids build-images build-loi build-manifest build-spine build-title build-toc clean compare-versions create-draft css-select dec2roman extract-ebook find-mismatched-dashes find-mismatched-diacritics find-unusual-characters help hyphenate interactive-replace lint make-url-safe modernize-spelling prepare-release recompose-epub renumber-endnotes roman2dec semanticate shift-endnotes shift-illustrations split-file titlecase typogrify unicode-names version word-count xpath"
if [[ $COMP_CWORD -gt 1 ]]; then
case "${COMP_WORDS[1]}" in
british2american)
Expand All @@ -27,6 +27,10 @@ _se(){
COMPREPLY+=($(compgen -W "-h --help -v --verbose" -- "${cur}"))
COMPREPLY+=($(compgen -d -X ".*" -- "${cur}"))
;;
build-loi)
COMPREPLY+=($(compgen -W "-a -d --default-link-text -h --help --prefer-alt-text" -- "${cur}"))
COMPREPLY+=($(compgen -d -X ".*" -- "${cur}"))
;;
build-manifest)
COMPREPLY+=($(compgen -W "-h --help -s --stdout" -- "${cur}"))
COMPREPLY+=($(compgen -d -X ".*" -- "${cur}"))
Expand Down
7 changes: 6 additions & 1 deletion se/completions/fish/se.fish
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function __fish_se_no_subcommand --description "Test if se has yet to be given the subcommand"
for i in (commandline -opc)
if contains -- $i british2american build build-ids build-images build-manifest build-spine build-title build-toc clean compare-versions create-draft css-select dec2roman extract-ebook find-mismatched-dashes find-mismatched-diacritics find-unusual-characters help hyphenate interactive-replace lint make-url-safe modernize-spelling prepare-release recompose-epub renumber-endnotes roman2dec semanticate shift-endnotes shift-illustrations split-file titlecase typogrify unicode-names version word-count xpath
if contains -- $i british2american build build-ids build-images build-loi build-manifest build-spine build-title build-toc clean compare-versions create-draft css-select dec2roman extract-ebook find-mismatched-dashes find-mismatched-diacritics find-unusual-characters help hyphenate interactive-replace lint make-url-safe modernize-spelling prepare-release recompose-epub renumber-endnotes roman2dec semanticate shift-endnotes shift-illustrations split-file titlecase typogrify unicode-names version word-count xpath
return 1
end
end
Expand Down Expand Up @@ -114,6 +114,11 @@ complete -c se -A -n "__fish_seen_subcommand_from prepare-release" -s r -l no-re
complete -c se -A -n "__fish_seen_subcommand_from prepare-release" -s w -l no-word-count -d "don’t calculate word count"
complete -c se -A -n "__fish_seen_subcommand_from prepare-release" -s v -l verbose -d "increase output verbosity"

complete -c se -n "__fish_se_no_subcommand" -a build-loi -d "Update the LoI file based on all <figure> elements that contain an <img>."
complete -c se -A -n "__fish_seen_subcommand_from build-loi" -s a -l prefer-alt-text -d "prefer alt text over <figcaption> for these <figure> IDs"
complete -c se -A -n "__fish_seen_subcommand_from build-loi" -s d -l default-link-text -d "link text to use if <figcaption> or alt text is absent or empty"
complete -c se -A -n "__fish_seen_subcommand_from build-loi" -s h -l help -x -d "show this help message and exit"

complete -c se -n "__fish_se_no_subcommand" -a build-manifest -d "Generate the <manifest> element for the given Standard Ebooks source directory and write it to the ebook’s metadata file."
complete -c se -A -n "__fish_seen_subcommand_from build-manifest" -s h -l help -x -d "show this help message and exit"
complete -c se -A -n "__fish_seen_subcommand_from build-manifest" -s s -l stdout -d "print to stdout instead of writing to the metadata file"
Expand Down
8 changes: 8 additions & 0 deletions se/completions/zsh/_se
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ case $state in
"build[Build an ebook from a Standard Ebook source directory.]" \
"build-ids[Change ID attributes for non-sectioning content to their expected values across the entire ebook. IDs must be globally unique and correctly referenced, and the ebook spine must be complete.]" \
"build-images[Build ebook cover and titlepage images in a Standard Ebook source directory.]" \
"build-loi[Update the LoI file based on all <figure> elements that contain an <img>.]" \
"build-manifest[Generate the <manifest> element for the given Standard Ebooks source directory and write it to the ebook’s metadata file.]" \
"build-spine[Generate the <spine> element for the given Standard Ebooks source directory and write it to the ebook’s metadata file.]" \
"build-title[Generate the title of an XHTML file based on its headings and update the file’s <title> element.]" \
Expand Down Expand Up @@ -83,6 +84,13 @@ case $state in
{-v,--verbose}'[increase output verbosity]' \
'*: :_directories'
;;
build-loi)
_arguments -s \
{-a,--prefer-alt-text}'[prefer alt text over <figcaption> for these <figure> IDs]' \
{-d,--default-link-text}'[link text to use if <figcaption> or alt text is absent or empty]' \
{-h,--help}'[show a help message and exit]' \
'*: :_directories'
;;
build-manifest)
_arguments -s \
{-h,--help}'[show a help message and exit]' \
Expand Down
49 changes: 48 additions & 1 deletion se/se_epub.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import datetime
import os
from pathlib import Path
from typing import Dict, List, Optional, Tuple, Union
from typing import Dict, List, Optional, Tuple, Union, Set

import git
from lxml import etree
Expand Down Expand Up @@ -913,6 +913,53 @@ def shift_illustrations(self, target_illustration_number: int, step: int = 1) ->
with open(file_path, "w", encoding="utf-8") as file:
file.write(dom.to_string())

def generate_loi(self, prefer_alt_text: Set[str], default_link_text: str) -> None:
"""
Updates the LoI file based on all <figure> elements that contain an
<img>. Text from the <figcaption>, if any, is preferred over that from
the <img>'s alt attribute, unless prefer_alt_text contains the
<figure>'s ID. If the resulting text is empty, default_link_text is used.
"""

figures = []
for file_path in self.spine_file_paths:
dom = self.get_dom(file_path)

for node in dom.xpath("/html/body//figure[@id and img]"):
figcaption = node.xpath("./figcaption")
figure_id = node.get_attr('id')
text = ""
if figcaption and figure_id not in prefer_alt_text:
text = figcaption[0].inner_text()
else:
text = node.xpath("./img")[0].get_attr("alt")

figures.append((f"{file_path.name}#{figure_id}", text))

dom = self.get_dom(self.loi_path)

ols = dom.xpath("/html/body/nav/ol")
if len(ols) != 1:
raise se.InvalidSeEbookException(f"LoI file contains unexpected number of [html]<ol/>[/]: [path][link=file://{self.loi_path}]{self.loi_path}[/][/].")

etree.strip_elements(ols[0].lxml_element, "li")

for (href, text) in figures:
a = se.easy_xml.EasyXmlElement("<a/>")
a.set_text(text or default_link_text)
a.set_attr("href", href)
p = se.easy_xml.EasyXmlElement("<p/>")
p.append(a)
li = se.easy_xml.EasyXmlElement("<li/>")
li.append(p)
ols[0].append(li)

try:
with open(self.loi_path, "w", encoding="utf-8") as file:
file.write(se.formatting.format_xhtml(dom.to_string()))
except Exception as ex:
raise se.InvalidSeEbookException(f"Couldn’t open LoI file: [path][link=file://{self.loi_path}]{self.loi_path}[/][/].") from ex

def set_release_timestamp(self) -> None:
"""
If this ebook has not yet been released, set the first release timestamp in the metadata file.
Expand Down
1 change: 1 addition & 0 deletions tests/draft_commands/build-loi/test-1/build-loi-command
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build-loi -a 'f-8' -d 'placeholder text'
Loading

0 comments on commit f7ef917

Please sign in to comment.