diff --git a/CHANGELOG.md b/CHANGELOG.md index 3afde0a54..9116bfc0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [v2.26.1] - 2025-05-22 + +* Revert changes to `BakeIframes` + ## [v2.26.0] - 2025-05-20 * Add `suppress_solution_title` to `bake_numbered_exercise` diff --git a/lib/kitchen/directions/bake_iframes/v1.rb b/lib/kitchen/directions/bake_iframes/v1.rb index 26916165c..d24b92b08 100644 --- a/lib/kitchen/directions/bake_iframes/v1.rb +++ b/lib/kitchen/directions/bake_iframes/v1.rb @@ -10,8 +10,13 @@ def bake(book:) iframes.each do |iframe| next if iframe.has_class?('os-is-iframe') # don't double-bake - iframe_link = '/404-this-link-should-be-replaced' - + iframe_link = \ + begin + iframe.rex_link + rescue StandardError + warn "Unable to find rex link for iframe #{iframe}" + iframe[:src] + end iframe.wrap('
') iframe.add_class('os-is-iframe') @@ -20,7 +25,7 @@ def bake(book:) iframe.prepend(child: <<~HTML - #{I18n.t(:iframe_link_text)} + #{I18n.t(:iframe_link_text)} HTML ) diff --git a/lib/kitchen/element_base.rb b/lib/kitchen/element_base.rb index d114ba4fd..b3e7e4d0d 100644 --- a/lib/kitchen/element_base.rb +++ b/lib/kitchen/element_base.rb @@ -967,6 +967,39 @@ def as_enumerator enumerator_class.new(search_query: search_query_that_found_me) { |block| block.yield(self) } end + def rex_link + self[:'data-is-for-rex-linking'] = 'true' + + element_with_ancestors = document.book.chapters.search_with( + Kitchen::PageElementEnumerator, Kitchen::CompositePageElementEnumerator + ).search('[data-is-for-rex-linking="true"]').first + + remove_attribute('data-is-for-rex-linking') + + unless element_with_ancestors + raise("Cannot create rex link to element #{self} - needs ancestors of both types chapter & page/composite_page" \ + "#{say_source_or_nil}" + ) + end + + book_slug = document.slug + chapter_count = element_with_ancestors.ancestor(:chapter).count_in(:book) + page_string = '' + page_title = '' + page = element_with_ancestors.ancestor(:page) if element_with_ancestors.has_ancestor?(:page) + if page&.is_introduction? + page_title = page.first('[data-type="document-title"]').text.slugify + elsif page + page_string = "#{page.count_in(:chapter) - 1}-" + page_title = page.title_text.slugify + else + page = element_with_ancestors.ancestor(:composite_page) + page_title = page.title.text.slugify + end + + "https://openstax.org/books/#{book_slug}/pages/#{chapter_count}-#{page_string}#{page_title}" + end + def add_platform_media(format) valid_formats = %w[screen print screenreader] raise "Media format invalid; valid formats are #{valid_formats}" unless valid_formats.include?(format) diff --git a/lib/kitchen/patches/string.rb b/lib/kitchen/patches/string.rb index b95277228..a08a878e8 100644 --- a/lib/kitchen/patches/string.rb +++ b/lib/kitchen/patches/string.rb @@ -10,4 +10,18 @@ class String def uncapitalize sub(/^[A-Z]/, &:downcase) end + + # Transform self to kebab case, returning a new string + # Example: "Star Wars: The Empire Strikes Back" -> "star-wars-the-empire-strikes-back" + # + # @return [String] + # + def slugify + I18n.transliterate( + strip.downcase + .gsub(/'/, '') + .gsub(/®/, ' r') + .gsub(/\u2014+/, '-') + ).gsub(/[^(\w\s)-]/, '').gsub(/[\s-]+/, '-') + end end diff --git a/spec/kitchen_spec/directions/bake_iframes/v1_spec.rb b/spec/kitchen_spec/directions/bake_iframes/v1_spec.rb index 0ff49545c..511a3d36c 100644 --- a/spec/kitchen_spec/directions/bake_iframes/v1_spec.rb +++ b/spec/kitchen_spec/directions/bake_iframes/v1_spec.rb @@ -63,4 +63,48 @@ described_class.new.bake(book: book_with_baked_iframes) expect(book_with_baked_iframes).to match_normalized_html(book_with_baked_iframes_snapshot) end + + context 'with exceptions' do + let(:book_with_iframe_no_slug) do + book_containing(html: + <<~HTML +
+
+
+

The Document: Title!

+
+ +
+
+
+ HTML + ) + end + + let(:book_with_iframe_no_id_on_media) do + book_containing(html: + <<~HTML + +
+
+
+

The Document: Title!

+
+ +
+
+
+ HTML + ) + end + + it 'warns when rex link can\'t be made - no slug' do + expect(Warning).to receive(:warn).with( + /Unable to find rex link for iframe @@ -3121,7 +3121,7 @@ an equation with parentheses.