From 8b9a7f243c67453d55669faa78b2e517e244965a Mon Sep 17 00:00:00 2001 From: Tyler Nullmeier Date: Tue, 25 Mar 2025 13:58:54 -0500 Subject: [PATCH 1/4] Add links to rex during link-single At this point we have already generated the book/page slugs, so we can easily reuse them --- bakery-src/scripts/link_rex.py | 7 ++----- bakery-src/scripts/link_single.py | 26 ++++++++++++++++++++++--- bakery-src/scripts/utils.py | 4 ++++ bakery-src/tests/test_bakery_scripts.py | 24 +++++++++++++++++++++++ 4 files changed, 53 insertions(+), 8 deletions(-) diff --git a/bakery-src/scripts/link_rex.py b/bakery-src/scripts/link_rex.py index e9a9322f..ade278f8 100644 --- a/bakery-src/scripts/link_rex.py +++ b/bakery-src/scripts/link_rex.py @@ -4,7 +4,7 @@ from lxml import etree -from .utils import unformatted_rex_links +from .utils import unformatted_rex_links, build_rex_url from .profiler import timed @@ -12,9 +12,6 @@ def update_doc_links(doc, book_slugs_by_uuid=None): """Modify links in doc""" - def _rex_url_builder(book, page): - return f"http://openstax.org/books/{book}/pages/{page}" - external_link_elems = unformatted_rex_links(doc) for node in external_link_elems: @@ -27,7 +24,7 @@ def _rex_url_builder(book, page): external_book_slug = book_slugs_by_uuid[ external_book_uuid] if book_slugs_by_uuid else node.attrib["data-book-slug"] external_page_slug = node.attrib["data-page-slug"] - node.attrib["href"] = _rex_url_builder( + node.attrib["href"] = build_rex_url( external_book_slug, external_page_slug ) print('AFTER!!:') diff --git a/bakery-src/scripts/link_single.py b/bakery-src/scripts/link_single.py index ec128844..fd3917a7 100644 --- a/bakery-src/scripts/link_single.py +++ b/bakery-src/scripts/link_single.py @@ -13,6 +13,7 @@ from .cnx_models import flatten_to_documents from lxml import etree from .profiler import timed +from .utils import build_rex_url @timed @@ -144,6 +145,7 @@ def transform_links( book_metadata = parse_book_metadata(binders, baked_meta_dir) uuid_by_slug = {entry["slug"]: entry["id"] for entry in book_metadata} + slug_by_uuid = dict(zip(*list(zip(*uuid_by_slug.items()))[::-1])) book_tree_by_uuid = { entry["id"]: entry["tree"] for entry in book_metadata } @@ -152,6 +154,26 @@ def transform_links( book_tree_by_uuid ) + for node in doc.xpath( + '//x:a[@data-needs-rex-link="true"]', + namespaces={"x": "http://www.w3.org/1999/xhtml"}, + ): + target_module_uuid = node.xpath( + 'ancestor::*[@data-type="page"]/@id', + namespaces={"x": "http://www.w3.org/1999/xhtml"}, + )[0] + if target_module_uuid.startswith("page_"): + target_module_uuid = target_module_uuid[5:] + canonical_book_uuid = canonical_map.get(target_module_uuid) + assert canonical_book_uuid, \ + f'Could not find book for page: {target_module_uuid}' + book_slug = slug_by_uuid.get(canonical_book_uuid) + assert book_slug, f'Could not find slug for book: {canonical_book_uuid}' + page_slug = page_slug_resolver(canonical_book_uuid, target_module_uuid) + assert page_slug, f'Could not find slug for page: {target_module_uuid}' + node.attrib['href'] = build_rex_url(book_slug, page_slug) + del node.attrib['data-needs-rex-link'] + # look up uuids for external module links for node in doc.xpath( '//x:a[@href and starts-with(@href, "/contents/")]', @@ -173,9 +195,7 @@ def transform_links( raise Exception( f"Could not find canonical book for {target_module_uuid}" ) - canonical_book_slug = next( - (slug for slug, uuid in uuid_by_slug.items() - if uuid == canonical_book_uuid)) + canonical_book_slug = slug_by_uuid[canonical_book_uuid] page_slug = page_slug_resolver(canonical_book_uuid, target_module_uuid) if page_slug is None: diff --git a/bakery-src/scripts/utils.py b/bakery-src/scripts/utils.py index b5c7de73..8ec51cf6 100644 --- a/bakery-src/scripts/utils.py +++ b/bakery-src/scripts/utils.py @@ -382,3 +382,7 @@ def patch_math_for_pandoc(doc, math_el_namespace): ): print("Found \\u0338 in math: converting to mtext", file=sys.stderr) node.tag = f"{{{math_el_namespace}}}mtext" + + +def build_rex_url(book, page): + return f"http://openstax.org/books/{book}/pages/{page}" diff --git a/bakery-src/tests/test_bakery_scripts.py b/bakery-src/tests/test_bakery_scripts.py index 6059dfc9..410eeac1 100644 --- a/bakery-src/tests/test_bakery_scripts.py +++ b/bakery-src/tests/test_bakery_scripts.py @@ -2857,6 +2857,7 @@ def test_link_single(tmp_path, mocker):

Page1

+ LINK 1

LINK 2

Date: Tue, 25 Mar 2025 14:14:56 -0500 Subject: [PATCH 2/4] Check other attributes are unchanged --- bakery-src/tests/test_bakery_scripts.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/bakery-src/tests/test_bakery_scripts.py b/bakery-src/tests/test_bakery_scripts.py index 410eeac1..a7726d9b 100644 --- a/bakery-src/tests/test_bakery_scripts.py +++ b/bakery-src/tests/test_bakery_scripts.py @@ -3016,20 +3016,22 @@ def test_link_single(tmp_path, mocker): '//x:a[@data-check-rex-link = "true"]', namespaces={"x": "http://www.w3.org/1999/xhtml"}, ) - _ = [link.attrib.pop("data-check-rex-link", None) for link in rex_links] # WHEN: The links are updated # THEN: 1. Their href changes # 2. The marker attribute is removed - # 3. their text is unchanged (this text may be localized) - check_links = [list(link.items()) + [link.text] for link in rex_links] + # 3. Their text is unchanged (this text may be localized) + # 4. Other attributes are unchanged + check_links = [list(link.items()) + [('text', link.text)] for link in rex_links] expected_links = [ [ + ('data-check-rex-link', 'true'), ('href', 'http://openstax.org/books/book1/pages/book1-page1'), - 'LINK 1' + ('text', 'LINK 1'), ], [ + ('data-check-rex-link', 'true'), ('href', 'http://openstax.org/books/book1/pages/book1-page2'), - 'LINK 2' + ('text', 'LINK 2'), ], ] assert check_links == expected_links From c7275be3331db6fed6168f161f98a558a9f39da1 Mon Sep 17 00:00:00 2001 From: Tyler Nullmeier Date: Mon, 31 Mar 2025 16:56:28 -0500 Subject: [PATCH 3/4] Fallback to using src from parent No idea when this would happen, but cookbook had a similar fallback --- bakery-src/scripts/link_single.py | 34 ++++++++++++++----------- bakery-src/tests/test_bakery_scripts.py | 8 ++++++ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/bakery-src/scripts/link_single.py b/bakery-src/scripts/link_single.py index fd3917a7..4e42d2b6 100644 --- a/bakery-src/scripts/link_single.py +++ b/bakery-src/scripts/link_single.py @@ -158,21 +158,25 @@ def transform_links( '//x:a[@data-needs-rex-link="true"]', namespaces={"x": "http://www.w3.org/1999/xhtml"}, ): - target_module_uuid = node.xpath( - 'ancestor::*[@data-type="page"]/@id', - namespaces={"x": "http://www.w3.org/1999/xhtml"}, - )[0] - if target_module_uuid.startswith("page_"): - target_module_uuid = target_module_uuid[5:] - canonical_book_uuid = canonical_map.get(target_module_uuid) - assert canonical_book_uuid, \ - f'Could not find book for page: {target_module_uuid}' - book_slug = slug_by_uuid.get(canonical_book_uuid) - assert book_slug, f'Could not find slug for book: {canonical_book_uuid}' - page_slug = page_slug_resolver(canonical_book_uuid, target_module_uuid) - assert page_slug, f'Could not find slug for page: {target_module_uuid}' - node.attrib['href'] = build_rex_url(book_slug, page_slug) - del node.attrib['data-needs-rex-link'] + try: + page_uuid = node.xpath('ancestor::*[@data-type="page"]/@id')[0] + if page_uuid.startswith("page_"): + page_uuid = page_uuid[5:] + book_uuid = canonical_map.get(page_uuid) + assert book_uuid, f'Could not find book for page: {page_uuid}' + book_slug = slug_by_uuid.get(book_uuid) + assert book_slug, f'Could not find slug for book: {book_uuid}' + page_slug = page_slug_resolver(book_uuid, page_uuid) + assert page_slug, f'Could not find slug for page: {page_uuid}' + node.attrib['href'] = build_rex_url(book_slug, page_slug) + except Exception as e: + parent_link = node.xpath('parent::*[@src]/@src') + assert parent_link, \ + f'Could not find link for element: {etree.tostring(node)}' + node.attrib['href'] = parent_link[0] + print(f"[WARNING]: {e} (used '{parent_link}' instead)") + finally: + del node.attrib['data-needs-rex-link'] # look up uuids for external module links for node in doc.xpath( diff --git a/bakery-src/tests/test_bakery_scripts.py b/bakery-src/tests/test_bakery_scripts.py index a7726d9b..decead7f 100644 --- a/bakery-src/tests/test_bakery_scripts.py +++ b/bakery-src/tests/test_bakery_scripts.py @@ -2853,6 +2853,9 @@ def test_link_single(tmp_path, mocker): +

Page1

@@ -3023,6 +3026,11 @@ def test_link_single(tmp_path, mocker): # 4. Other attributes are unchanged check_links = [list(link.items()) + [('text', link.text)] for link in rex_links] expected_links = [ + [ + ('data-check-rex-link', 'true'), + ('href', 'http://example.com'), + ('text', 'outside page/chapter'), + ], [ ('data-check-rex-link', 'true'), ('href', 'http://openstax.org/books/book1/pages/book1-page1'), From 89c81ffb865a5616472d05a7c5eaf635ccd29268 Mon Sep 17 00:00:00 2001 From: Tyler Nullmeier Date: Tue, 1 Apr 2025 09:55:28 -0500 Subject: [PATCH 4/4] Fix lint; remove version from makefile Version wasn't used for anything and it never worked here anyway --- nebuchadnezzar/Makefile | 21 --------------------- nebuchadnezzar/nebu/models/book_part.py | 2 +- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/nebuchadnezzar/Makefile b/nebuchadnezzar/Makefile index 1d56a067..01e7a69f 100644 --- a/nebuchadnezzar/Makefile +++ b/nebuchadnezzar/Makefile @@ -46,7 +46,6 @@ help : @echo " * pyenv -- ${_SHORT_DESC_PYENV}" @echo " * test -- ${_SHORT_DESC_TEST}" @echo " * check-dist -- ${_SHORT_DESC_CHECK_DIST}" - @echo " * version -- Print the version" @echo "" @echo "Where can be:" # alphbetical please @echo "" @@ -89,26 +88,6 @@ test : $(STATEDIR)/env/pyvenv.cfg # /Test -# ### -# Version -# ### - - -curr_tag := $(shell git describe --tags $$(git rev-list --tags --max-count=1)) -curr_tag_rev := $(shell git rev-parse "$(curr_tag)^0") -head_rev := $(shell git rev-parse HEAD) -head_short_rev := $(shell git rev-parse --short HEAD) -ifeq ($(curr_tag_rev),$(head_rev)) - version := $(curr_tag) -else - version := $(curr_tag)-dev$(head_short_rev) -endif - -version help-version : .git - @echo $(version) - -# /Version - # ### # Lint diff --git a/nebuchadnezzar/nebu/models/book_part.py b/nebuchadnezzar/nebu/models/book_part.py index 2c8d7970..28043926 100644 --- a/nebuchadnezzar/nebu/models/book_part.py +++ b/nebuchadnezzar/nebu/models/book_part.py @@ -101,7 +101,7 @@ def new_doc(id): parent_stack = [] def handler(event, elm): - nonlocal parent_part, current_part, parent_stack + nonlocal parent_part, current_part if elm.tag == TITLE_TAG and event == "start": title = elm.text assert (